@blamejs/exceptd-skills 0.16.25 → 0.16.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -5
- package/ARCHITECTURE.md +3 -3
- package/CHANGELOG.md +28 -0
- package/CONTEXT.md +2 -2
- package/README.md +6 -6
- package/agents/threat-researcher.md +2 -2
- package/bin/exceptd.js +41 -8
- package/data/_indexes/_meta.json +41 -40
- package/data/_indexes/activity-feed.json +240 -240
- package/data/_indexes/catalog-summaries.json +3 -3
- package/data/_indexes/currency.json +64 -64
- package/data/_indexes/jurisdiction-map.json +31 -158
- package/data/_indexes/recipes.json +1 -1
- package/data/_indexes/section-offsets.json +510 -510
- package/data/_indexes/summary-cards.json +33 -33
- package/data/_indexes/token-budget.json +200 -200
- package/data/atlas-ttps.json +7 -7
- package/data/attack-techniques.json +5 -5
- package/data/framework-control-gaps.json +3 -3
- package/lib/auto-discovery.js +15 -9
- package/lib/collectors/library-author.js +26 -9
- package/lib/collectors/secrets.js +8 -1
- package/lib/cvss.js +108 -0
- package/lib/lint-skills.js +6 -1
- package/lib/playbook-runner.js +17 -4
- package/lib/prefetch.js +97 -5
- package/lib/refresh-external.js +25 -13
- package/lib/schemas/manifest.schema.json +1 -1
- package/lib/schemas/skill-frontmatter.schema.json +1 -1
- package/lib/validate-indexes.js +5 -0
- package/lib/version-pins.js +3 -3
- package/manifest-snapshot.json +2 -2
- package/manifest-snapshot.sha256 +1 -1
- package/manifest.json +124 -124
- package/orchestrator/pipeline.js +16 -4
- package/package.json +1 -1
- package/sbom.cdx.json +170 -140
- package/scripts/build-indexes.js +12 -1
- package/scripts/builders/catalog-summaries.js +1 -1
- package/scripts/builders/recipes.js +1 -1
- package/scripts/check-sbom-currency.js +76 -14
- package/scripts/refresh-sbom.js +1 -1
- package/scripts/run-e2e-scenarios.js +48 -17
- package/scripts/sync-package-description.js +74 -0
- package/scripts/verify-shipped-tarball.js +18 -7
- package/skills/age-gates-child-safety/skill.md +3 -3
- package/skills/ai-attack-surface/skill.md +4 -4
- package/skills/ai-c2-detection/skill.md +5 -5
- package/skills/api-security/skill.md +2 -2
- package/skills/attack-surface-pentest/skill.md +4 -4
- package/skills/cloud-security/skill.md +3 -3
- package/skills/compliance-theater/skill.md +3 -3
- package/skills/container-runtime-security/skill.md +3 -3
- package/skills/coordinated-vuln-disclosure/skill.md +2 -2
- package/skills/defensive-countermeasure-mapping/skill.md +3 -3
- package/skills/dlp-gap-analysis/skill.md +5 -5
- package/skills/exploit-scoring/skill.md +2 -2
- package/skills/framework-gap-analysis/skill.md +4 -4
- package/skills/fuzz-testing-strategy/skill.md +2 -2
- package/skills/incident-response-playbook/skill.md +3 -3
- package/skills/mcp-agent-trust/skill.md +2 -2
- package/skills/mlops-security/skill.md +3 -3
- package/skills/ot-ics-security/skill.md +3 -3
- package/skills/policy-exception-gen/skill.md +3 -3
- package/skills/pqc-first/skill.md +2 -2
- package/skills/rag-pipeline-security/skill.md +4 -4
- package/skills/ransomware-response/skill.md +2 -2
- package/skills/sector-energy/skill.md +2 -2
- package/skills/sector-federal-government/skill.md +2 -2
- package/skills/sector-financial/skill.md +4 -4
- package/skills/sector-healthcare/skill.md +3 -3
- package/skills/security-maturity-tiers/skill.md +1 -1
- package/skills/skill-update-loop/skill.md +6 -6
- package/skills/supply-chain-integrity/skill.md +2 -2
- package/skills/threat-model-currency/skill.md +8 -8
- package/skills/threat-modeling-methodology/skill.md +2 -2
- package/skills/webapp-security/skill.md +2 -2
- package/skills/zeroday-gap-learn/skill.md +3 -3
- package/sources/validators/cve-validator.js +27 -18
|
@@ -43,7 +43,7 @@ forward_watch:
|
|
|
43
43
|
- Unified Kill Chain successor revision (Pols, post-v3.0)
|
|
44
44
|
- LINDDUN-GO and LINDDUN-PRO updates incorporating LLM privacy threats
|
|
45
45
|
- PASTA v2 updates incorporating AI/ML application threats
|
|
46
|
-
last_threat_review: "2026-
|
|
46
|
+
last_threat_review: "2026-06-10"
|
|
47
47
|
discovery_mode: "standalone" # operator-reached via `exceptd brief threat-modeling-methodology` or `exceptd ask`; not chained into any playbook's direct.skill_chain by design
|
|
48
48
|
---
|
|
49
49
|
|
|
@@ -132,7 +132,7 @@ Threat-modelling methodologies are *consumers* of the TTP catalog, not contribut
|
|
|
132
132
|
| Cyber Kill Chain | Linear 7-stage intrusion timeline | Per stage: ATT&CK TTPs | Cloud-native / serverless / AI-pipeline scenarios fit the timeline poorly; lateral movement assumptions break in ephemeral compute. |
|
|
133
133
|
| Diamond Model | Adversary–capability–infrastructure–victim diamond | Per intrusion event: TTPs become adversary capabilities; pivot to other diamonds | Built for IR / SOC, not for design-phase threat modelling — pair with STRIDE/PASTA during design and Diamond during operate phase. |
|
|
134
134
|
| MITRE Unified Kill Chain (v3.0, 2024) | 18 phases spanning initial access through objectives | Per phase: ATLAS and ATT&CK TTPs assigned to phases that cover both classical and AI-augmented attacks | Most comprehensive single methodology, but weak on privacy threats — pair with LINDDUN. |
|
|
135
|
-
| AI-system threat modeling (composite) | Augmented DFD with AI actors and AI trust boundaries | Full ATLAS
|
|
135
|
+
| AI-system threat modeling (composite) | Augmented DFD with AI actors and AI trust boundaries | Full ATLAS v2026.05 catalogue (every `AML.T*` key in `data/atlas-ttps.json`) | Methodology not yet standardised — this skill operationalises it. |
|
|
136
136
|
| Agent-based threat modeling | Actor graph with autonomous agents, MCP plugins, tool-call boundaries | CVE-2026-30615 (MCP RCE), CVE-2025-53773 (prompt-injection RCE), AML.T0051, AML.T0096 | Methodology not yet standardised — this skill operationalises it. |
|
|
137
137
|
|
|
138
138
|
The truth set for any composite model is: every `AML.T*` key in `data/atlas-ttps.json`, plus every `attack_refs` entry across every CVE in `data/cve-catalog.json`, plus the CWE root-cause classes in `data/cwe-catalog.json`. A model that does not address each, or document a reasoned exclusion for each, is non-current by construction (and should be re-run through `threat-model-currency`).
|
|
@@ -65,7 +65,7 @@ d3fend_refs:
|
|
|
65
65
|
- D3-MFA
|
|
66
66
|
forward_watch:
|
|
67
67
|
- NGINX Rift CVE-2026-42945 (disclosed 2026-05-13, source depthfirst) — KEV-watch predicted CISA KEV listing by 2026-05-29; AI-assisted discovery angle; track for active-exploitation confirmation and patch advisory affecting front-door web app deployments
|
|
68
|
-
last_threat_review: "2026-
|
|
68
|
+
last_threat_review: "2026-06-10"
|
|
69
69
|
discovery_mode: "standalone" # operator-reached via `exceptd brief webapp-security` or `exceptd ask`; not chained into any playbook's direct.skill_chain by design
|
|
70
70
|
---
|
|
71
71
|
|
|
@@ -105,7 +105,7 @@ Webapps still ship CWE-79 (Cross-Site Scripting), CWE-89 (SQL Injection), and CW
|
|
|
105
105
|
|
|
106
106
|
---
|
|
107
107
|
|
|
108
|
-
## TTP Mapping (MITRE ATT&CK Enterprise + ATLAS
|
|
108
|
+
## TTP Mapping (MITRE ATT&CK Enterprise + ATLAS v2026.05)
|
|
109
109
|
|
|
110
110
|
| TTP ID | Technique | Webapp Manifestation | CWE Root-Causes | Framework Coverage |
|
|
111
111
|
|---|---|---|---|---|
|
|
@@ -23,7 +23,7 @@ forward_watch:
|
|
|
23
23
|
- New ATLAS TTP additions in each ATLAS release
|
|
24
24
|
- Framework updates that close previously open gaps
|
|
25
25
|
- Vendor advisories for MCP/AI tool supply chain CVEs
|
|
26
|
-
last_threat_review: "2026-
|
|
26
|
+
last_threat_review: "2026-06-10"
|
|
27
27
|
discovery_mode: "standalone" # operator-reached via `exceptd brief zeroday-gap-learn` or `exceptd ask`; not chained into any playbook's direct.skill_chain by design
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -79,7 +79,7 @@ This skill is meta — it does not pin to a single TTP class. The learning loop
|
|
|
79
79
|
| Input Catalog | Role in the Learning Loop |
|
|
80
80
|
|---|---|
|
|
81
81
|
| `data/cve-catalog.json` | The CVE-level corpus: each entry is a candidate lesson input. New entries trigger a new loop run. |
|
|
82
|
-
| `data/atlas-ttps.json` (MITRE ATLAS
|
|
82
|
+
| `data/atlas-ttps.json` (MITRE ATLAS v2026.05) | The AI/ML TTP taxonomy. Attack-vector extraction maps the CVE's mechanism to an ATLAS ID (e.g., AML.T0096 for SesameOp AI-as-C2). |
|
|
83
83
|
| `data/framework-control-gaps.json` | The control-gap corpus. Framework-coverage assessment writes into this file via new entries or `status` updates. |
|
|
84
84
|
| `data/zeroday-lessons.json` | The output corpus. Each completed loop produces one entry here — the durable artifact of the lesson. |
|
|
85
85
|
|
|
@@ -369,7 +369,7 @@ Run through each applicable framework:
|
|
|
369
369
|
- CIS Controls v8 (which control?)
|
|
370
370
|
- ASD Essential 8 (which mitigation?)
|
|
371
371
|
- ISO 27001:2022 (which control?)
|
|
372
|
-
- MITRE ATLAS
|
|
372
|
+
- MITRE ATLAS v2026.05 (which TTP? Is it covered?)
|
|
373
373
|
|
|
374
374
|
For each: Covered (adequate) / Covered (insufficient) / Missing entirely
|
|
375
375
|
|
|
@@ -38,6 +38,8 @@ const NVD_API = 'https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=';
|
|
|
38
38
|
const KEV_FEED = 'https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json';
|
|
39
39
|
const EPSS_API = 'https://api.first.org/data/v1/epss?cve=';
|
|
40
40
|
const REQUEST_TIMEOUT_MS = 10_000;
|
|
41
|
+
|
|
42
|
+
const { selectNvdCvss, cvssVersionOf } = require('../../lib/cvss');
|
|
41
43
|
const EPSS_DRIFT_THRESHOLD = 0.05; // |Δscore| or |Δpercentile| > 0.05 flags drift
|
|
42
44
|
const USER_AGENT = 'exceptd-security/cve-validator (+https://exceptd.com)';
|
|
43
45
|
|
|
@@ -93,22 +95,19 @@ function resetKevCache() {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
function extractNvdCvss(nvdJson) {
|
|
96
|
-
// NVD response: vulnerabilities[0].cve.metrics.
|
|
98
|
+
// NVD response: vulnerabilities[0].cve.metrics.cvssMetricV3x/V2[].cvssData.
|
|
99
|
+
// Prefer the newest CVSS version present (Primary within it) and normalize a
|
|
100
|
+
// bare v2 vector to its canonical prefix — NVD tags the legacy v2 metric
|
|
101
|
+
// "Primary" on pre-v3 CVEs over a v3.1 "Secondary", so selecting by type
|
|
102
|
+
// alone would report a stale v2 score as the upstream value.
|
|
97
103
|
const vuln = nvdJson?.vulnerabilities?.[0]?.cve;
|
|
98
104
|
if (!vuln) return null;
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
...(metrics.cvssMetricV31 || []),
|
|
102
|
-
...(metrics.cvssMetricV30 || []),
|
|
103
|
-
...(metrics.cvssMetricV2 || []),
|
|
104
|
-
];
|
|
105
|
-
// Prefer Primary type if present
|
|
106
|
-
const primary = ordered.find(m => m.type === 'Primary') || ordered[0];
|
|
107
|
-
if (!primary?.cvssData) return null;
|
|
105
|
+
const up = selectNvdCvss(vuln.metrics);
|
|
106
|
+
if (!up) return null;
|
|
108
107
|
return {
|
|
109
|
-
score:
|
|
110
|
-
vector:
|
|
111
|
-
source:
|
|
108
|
+
score: up.baseScore,
|
|
109
|
+
vector: up.vector,
|
|
110
|
+
source: up.source,
|
|
112
111
|
};
|
|
113
112
|
}
|
|
114
113
|
|
|
@@ -270,13 +269,23 @@ async function validateCve(cveId, localEntry) {
|
|
|
270
269
|
}
|
|
271
270
|
|
|
272
271
|
// --- Compare CVSS (only if NVD reachable & has data) ---
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
// Guard against cross-version downgrades: NVD often carries only a legacy v2
|
|
273
|
+
// metric for older CVEs while the catalog is curated to CVSS:3.1. Surfacing
|
|
274
|
+
// (and, on `refresh --apply`, writing) the lower v2 score/vector over a
|
|
275
|
+
// curated v3.x value is a downgrade, not a drift. Mirror the cache path's
|
|
276
|
+
// suppression (lib/refresh-external.js nvdDiffFromCache) so the live and
|
|
277
|
+
// cache refresh paths converge; a same-version re-score still flows through.
|
|
278
|
+
const localCvssVersion = cvssVersionOf(local.cvss_vector);
|
|
279
|
+
const fetchedCvssVersion = cvssVersionOf(fetched.cvss_vector);
|
|
280
|
+
const cvssIsDowngrade =
|
|
281
|
+
fetchedCvssVersion != null && localCvssVersion != null && fetchedCvssVersion < localCvssVersion;
|
|
282
|
+
if (cveFoundInNvd && !cvssIsDowngrade) {
|
|
283
|
+
if (fetched.cvss_score !== null && local.cvss_score !== null &&
|
|
284
|
+
Math.abs(fetched.cvss_score - local.cvss_score) > 0.05) {
|
|
275
285
|
pushDiscrepancy(discrepancies, 'cvss_score', local.cvss_score, fetched.cvss_score, 'high');
|
|
276
286
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (fetched.cvss_vector !== local.cvss_vector) {
|
|
287
|
+
if (fetched.cvss_vector && local.cvss_vector &&
|
|
288
|
+
fetched.cvss_vector !== local.cvss_vector) {
|
|
280
289
|
pushDiscrepancy(discrepancies, 'cvss_vector', local.cvss_vector, fetched.cvss_vector, 'medium');
|
|
281
290
|
}
|
|
282
291
|
}
|