@blamejs/exceptd-skills 0.18.15 → 0.18.16
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/CHANGELOG.md +12 -0
- package/bin/exceptd.js +36 -1
- package/data/_indexes/_meta.json +2 -2
- package/lib/playbook-runner.js +89 -13
- package/manifest.json +53 -53
- package/package.json +1 -1
- package/sbom.cdx.json +16 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.18.16 — 2026-06-22
|
|
4
|
+
|
|
5
|
+
A correctness pass on the evidence-output and attestation surfaces.
|
|
6
|
+
|
|
7
|
+
SARIF finding results always carry a location now. A result with no `locations` is silently dropped by GitHub Code Scanning; previously only playbooks whose look-artifact sources happened to be bare file paths got one, so most playbooks' (prose/glob/command sources) findings were emitted location-less and disappeared from the alerts list. Each finding without a concrete file now carries a rule-scoped logical location, keeping it visible and attributable; a physical file location is still used whenever the agent supplied one.
|
|
8
|
+
|
|
9
|
+
`attest diff` no longer reports identical evidence as changed. The artifact diff was keyed by the operator-chosen observation key rather than the indicator the observation targeted, so two attestations with the same finding under different observation keys (a different collector run, the array vs object evidence shape, reordered observations) showed every artifact as added-and-removed with zero unchanged. The diff is now keyed by the stable indicator id, so identical evidence compares as unchanged.
|
|
10
|
+
|
|
11
|
+
Risk-acceptance exception language now reports its unresolved placeholders. The auditor-ready exception text is filled from operator-supplied values that a standard run does not pre-stage, so it could ship literal `<MISSING:…>` tokens; the exception now carries a `missing_interpolation_vars` list (and surfaces a runtime error) naming exactly which values still need filling, matching the notification-draft behavior.
|
|
12
|
+
|
|
13
|
+
CSAF advisories bind their per-version affected products. The product tree's per-version product entries were defined but never referenced from any vulnerability, so a dashboard correlating affected products to the tree saw only the generic synthetic product; each CVE's version entries are now bound into its `product_status`.
|
|
14
|
+
|
|
3
15
|
## 0.18.15 — 2026-06-22
|
|
4
16
|
|
|
5
17
|
Indicator-gated escalations and playbook chains now fire when their indicators are detected. An escalation or `feeds_into` written as `<indicator-id> == true` (the catalog's standard form) resolved only when that id was also passed as a raw signal; the normal scan path delivers detections separately, so on a real `exceptd collect <playbook>` these escalations and downstream chains stayed silent even when the indicator was found. Fired indicators are now bound into the escalation, chain, and remediation-precondition contexts, so a detection drives the condition that gates on it. An operator can still override a specific indicator, and engine-computed values still take precedence.
|
package/bin/exceptd.js
CHANGED
|
@@ -6554,6 +6554,39 @@ function submissionHasData(submission) {
|
|
|
6554
6554
|
|| nonEmpty(submission.signal_overrides)
|
|
6555
6555
|
|| nonEmpty(submission.observations);
|
|
6556
6556
|
}
|
|
6557
|
+
// attest diff compares artifacts by map key. normalizeSubmission keys
|
|
6558
|
+
// flat-shape artifacts by the operator-chosen OBSERVATION key (obs-kver, x1, an
|
|
6559
|
+
// array index, …), NOT by the stable indicator id the observation targeted — so
|
|
6560
|
+
// two attestations with identical (indicator, value) evidence under different
|
|
6561
|
+
// observation keys diffed as all-added/all-removed (unchanged_count 0), while the
|
|
6562
|
+
// correctly-keyed signal_override_diff on the same comparison showed the true
|
|
6563
|
+
// unchanged result. Re-key the artifact map by the stable indicator id (recovered
|
|
6564
|
+
// from normalizeSubmission's _signal_origins, which maps indicator -> obs-key)
|
|
6565
|
+
// before diffing, falling back to the original key when an observation carries no
|
|
6566
|
+
// indicator binding. Diff-only — does NOT touch normalizeSubmission's map or the
|
|
6567
|
+
// evidence_hash.
|
|
6568
|
+
function rekeyArtifactsByStableId(artifacts, signalOrigins) {
|
|
6569
|
+
if (!artifacts || !signalOrigins || typeof signalOrigins !== "object") return artifacts || {};
|
|
6570
|
+
const obsKeyToIndicator = {};
|
|
6571
|
+
for (const [indicatorId, obsKey] of Object.entries(signalOrigins)) {
|
|
6572
|
+
if (typeof obsKey === "string") obsKeyToIndicator[obsKey] = indicatorId;
|
|
6573
|
+
}
|
|
6574
|
+
const originalKeys = new Set(Object.keys(artifacts));
|
|
6575
|
+
const out = {};
|
|
6576
|
+
for (const [k, v] of Object.entries(artifacts)) {
|
|
6577
|
+
const mapped = obsKeyToIndicator[k];
|
|
6578
|
+
// Re-key to the stable indicator id ONLY when it won't drop an artifact: the
|
|
6579
|
+
// indicator id must not already be a DISTINCT original artifact key, and must
|
|
6580
|
+
// not have been claimed by an earlier re-keyed entry. On any such collision,
|
|
6581
|
+
// keep the original key so no artifact is silently overwritten / lost from
|
|
6582
|
+
// the diff (two observations sharing one indicator, or an artifact key that
|
|
6583
|
+
// already equals an indicator id).
|
|
6584
|
+
const stable = (mapped && mapped !== k && !originalKeys.has(mapped)
|
|
6585
|
+
&& !Object.prototype.hasOwnProperty.call(out, mapped)) ? mapped : k;
|
|
6586
|
+
out[stable] = v;
|
|
6587
|
+
}
|
|
6588
|
+
return out;
|
|
6589
|
+
}
|
|
6557
6590
|
function normalizedArtifacts(submission, runner, playbookId, applyEmptyFallback = true) {
|
|
6558
6591
|
if (!submission || typeof submission !== "object") {
|
|
6559
6592
|
return applyEmptyFallback ? (_playbookArtifactCatalog(runner, playbookId) || {}) : {};
|
|
@@ -6568,7 +6601,9 @@ function normalizedArtifacts(submission, runner, playbookId, applyEmptyFallback
|
|
|
6568
6601
|
const pb = runner.loadPlaybook ? runner.loadPlaybook(playbookId) : null;
|
|
6569
6602
|
if (pb) {
|
|
6570
6603
|
const norm = runner.normalizeSubmission({ observations: submission.observations }, pb);
|
|
6571
|
-
if (norm && norm.artifacts && Object.keys(norm.artifacts).length > 0)
|
|
6604
|
+
if (norm && norm.artifacts && Object.keys(norm.artifacts).length > 0) {
|
|
6605
|
+
return rekeyArtifactsByStableId(norm.artifacts, norm._signal_origins);
|
|
6606
|
+
}
|
|
6572
6607
|
}
|
|
6573
6608
|
} catch { /* fall through */ }
|
|
6574
6609
|
}
|
package/data/_indexes/_meta.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "1.1.0",
|
|
3
|
-
"generated_at": "2026-06-
|
|
3
|
+
"generated_at": "2026-06-22T17:11:04.498Z",
|
|
4
4
|
"generator": "scripts/build-indexes.js",
|
|
5
5
|
"source_count": 64,
|
|
6
6
|
"source_hashes": {
|
|
7
|
-
"manifest.json": "
|
|
7
|
+
"manifest.json": "c8376cbda42a9657b6a5d50f75d8c08a0bcab7c8456340042be7998133922ecb",
|
|
8
8
|
"README.md": "e7b854e7db9a364a1b368b5084b4f0c2a8282f0459ce39800ac1d1dabdc06074",
|
|
9
9
|
"data/atlas-ttps.json": "5bc59e23d6c2defa54168de161a0825299b9cc4a49c6b26df2dae70b4f42eedf",
|
|
10
10
|
"data/attack-techniques.json": "53c6f248760eecb11a0354f74ab467a5814e95075a686b9b3bf18c34e2f7435e",
|
package/lib/playbook-runner.js
CHANGED
|
@@ -1994,14 +1994,26 @@ function close(playbookId, directiveId, analyzeResult, validateResult, agentSign
|
|
|
1994
1994
|
const triggered = evalCondition(c.exception_generation.trigger_condition, closeEvalCtx, playbook);
|
|
1995
1995
|
if (triggered) {
|
|
1996
1996
|
const t = c.exception_generation.exception_template;
|
|
1997
|
+
// Track unresolved ${placeholder} tokens the SAME way the draft_notification
|
|
1998
|
+
// render does (missing_interpolation_vars). Exception-template tokens are
|
|
1999
|
+
// operator-fill values (affected_host_count, compensating_controls,
|
|
2000
|
+
// patch_available_status, …) that analyzeFindingShape does NOT supply and
|
|
2001
|
+
// that operators rarely pre-stage on the standard `exceptd run` path, so the
|
|
2002
|
+
// auditor-ready risk-acceptance language otherwise ships literal
|
|
2003
|
+
// `<MISSING:…>` tokens with no machine-readable signal of which placeholders
|
|
2004
|
+
// failed. Surface them as exception.missing_interpolation_vars (empty when
|
|
2005
|
+
// all resolved) so a `ci`/JSON consumer — and the operator filling the
|
|
2006
|
+
// exception — sees exactly what still needs a value.
|
|
2007
|
+
const exMissing = [];
|
|
2008
|
+
const findingShape = (() => { try { return analyzeFindingShape(analyzeResult); } catch { return {}; } })();
|
|
1997
2009
|
exception = {
|
|
1998
|
-
scope: interpolate(t.scope, { ...agentSignals, ...
|
|
2010
|
+
scope: interpolate(t.scope, { ...agentSignals, ...findingShape }, exMissing),
|
|
1999
2011
|
duration: t.duration,
|
|
2000
2012
|
compensating_controls: t.compensating_controls,
|
|
2001
2013
|
risk_acceptance_owner: t.risk_acceptance_owner,
|
|
2002
2014
|
auditor_ready_language: interpolate(t.auditor_ready_language, {
|
|
2003
2015
|
...agentSignals,
|
|
2004
|
-
...
|
|
2016
|
+
...findingShape,
|
|
2005
2017
|
framework_id: playbook.domain.frameworks_in_scope[0] || 'unspecified',
|
|
2006
2018
|
control_id: analyzeResult.framework_gap_mapping?.[0]?.claimed_control || 'unspecified',
|
|
2007
2019
|
ciso_name: agentSignals.ciso_name || '<CISO NAME>',
|
|
@@ -2010,8 +2022,16 @@ function close(playbookId, directiveId, analyzeResult, validateResult, agentSign
|
|
|
2010
2022
|
// same auditor-facing date.
|
|
2011
2023
|
acceptance_date: (deterministic ? frozenEpoch : new Date().toISOString()).slice(0, 10),
|
|
2012
2024
|
duration_expiry: agentSignals.duration_expiry || 'until vendor patch'
|
|
2013
|
-
})
|
|
2025
|
+
}, exMissing),
|
|
2026
|
+
missing_interpolation_vars: exMissing,
|
|
2014
2027
|
};
|
|
2028
|
+
// Make the unresolved-placeholder gap observable to JSON/ci consumers, not
|
|
2029
|
+
// just present on the exception object.
|
|
2030
|
+
if (exMissing.length && Array.isArray(runOpts._runErrors)) {
|
|
2031
|
+
pushRunError(runOpts._runErrors,
|
|
2032
|
+
{ kind: 'exception_unresolved_placeholders', placeholders: exMissing.slice() },
|
|
2033
|
+
{ dedupeKey: e => (e.placeholders || []).join(',') });
|
|
2034
|
+
}
|
|
2015
2035
|
}
|
|
2016
2036
|
}
|
|
2017
2037
|
|
|
@@ -2330,12 +2350,23 @@ function vulnIdToUrn(id) {
|
|
|
2330
2350
|
function buildCsafBranches(matchedCves, runOpts) {
|
|
2331
2351
|
// Build a (vendor → product → Set<version>) map.
|
|
2332
2352
|
const tree = new Map();
|
|
2333
|
-
|
|
2353
|
+
// Track which CVE contributed each leaf so the emitted CSAFPID-N product_ids
|
|
2354
|
+
// can be bound back into that CVE's vulnerabilities[].product_status — without
|
|
2355
|
+
// this the branch tree's per-version products are referenced by nothing and a
|
|
2356
|
+
// CSAF consumer correlating product_status to the tree resolves only the
|
|
2357
|
+
// generic synthetic product. leafKey = vendor\0product\0version.
|
|
2358
|
+
const leafKey = (vendor, product, version) => JSON.stringify([vendor, product, version]);
|
|
2359
|
+
const cveLeaves = new Map(); // cve_id → Set<leafKey>
|
|
2360
|
+
const addLeaf = (vendor, product, version, cveId) => {
|
|
2334
2361
|
if (!vendor || !product || !version) return;
|
|
2335
2362
|
if (!tree.has(vendor)) tree.set(vendor, new Map());
|
|
2336
2363
|
const products = tree.get(vendor);
|
|
2337
2364
|
if (!products.has(product)) products.set(product, new Set());
|
|
2338
2365
|
products.get(product).add(version);
|
|
2366
|
+
if (cveId) {
|
|
2367
|
+
if (!cveLeaves.has(cveId)) cveLeaves.set(cveId, new Set());
|
|
2368
|
+
cveLeaves.get(cveId).add(leafKey(vendor, product, version));
|
|
2369
|
+
}
|
|
2339
2370
|
};
|
|
2340
2371
|
|
|
2341
2372
|
// Comparison / range operators that appear between a package name and a
|
|
@@ -2386,7 +2417,7 @@ function buildCsafBranches(matchedCves, runOpts) {
|
|
|
2386
2417
|
if (Array.isArray(c.affected_products) && c.affected_products.length > 0) {
|
|
2387
2418
|
for (const ap of c.affected_products) {
|
|
2388
2419
|
if (ap && typeof ap === 'object' && ap.vendor && ap.product && ap.version) {
|
|
2389
|
-
addLeaf(String(ap.vendor), String(ap.product), String(ap.version));
|
|
2420
|
+
addLeaf(String(ap.vendor), String(ap.product), String(ap.version), c.cve_id);
|
|
2390
2421
|
}
|
|
2391
2422
|
}
|
|
2392
2423
|
continue;
|
|
@@ -2396,7 +2427,7 @@ function buildCsafBranches(matchedCves, runOpts) {
|
|
|
2396
2427
|
for (const comp of components) {
|
|
2397
2428
|
const parsed = parseComponentString(comp);
|
|
2398
2429
|
if (parsed) {
|
|
2399
|
-
addLeaf(parsed.vendor, parsed.product, parsed.version);
|
|
2430
|
+
addLeaf(parsed.vendor, parsed.product, parsed.version, c.cve_id);
|
|
2400
2431
|
} else if (typeof comp === 'string' && comp.trim() && runOpts && Array.isArray(runOpts._runErrors)) {
|
|
2401
2432
|
pushRunError(runOpts._runErrors, {
|
|
2402
2433
|
kind: 'csaf_branch_unparseable',
|
|
@@ -2409,6 +2440,7 @@ function buildCsafBranches(matchedCves, runOpts) {
|
|
|
2409
2440
|
|
|
2410
2441
|
// Sort + emit.
|
|
2411
2442
|
const productIds = [];
|
|
2443
|
+
const leafKeyToPid = new Map();
|
|
2412
2444
|
let pidCounter = 0;
|
|
2413
2445
|
const vendors = Array.from(tree.keys()).sort();
|
|
2414
2446
|
const branches = vendors.map(vendor => {
|
|
@@ -2425,6 +2457,7 @@ function buildCsafBranches(matchedCves, runOpts) {
|
|
|
2425
2457
|
branches: versions.map(version => {
|
|
2426
2458
|
const pid = `CSAFPID-${pidCounter++}`;
|
|
2427
2459
|
productIds.push({ vendor, product, version, product_id: pid });
|
|
2460
|
+
leafKeyToPid.set(leafKey(vendor, product, version), pid);
|
|
2428
2461
|
return {
|
|
2429
2462
|
category: 'product_version',
|
|
2430
2463
|
name: version,
|
|
@@ -2438,7 +2471,15 @@ function buildCsafBranches(matchedCves, runOpts) {
|
|
|
2438
2471
|
}),
|
|
2439
2472
|
};
|
|
2440
2473
|
});
|
|
2441
|
-
|
|
2474
|
+
// Per-CVE CSAFPID binding so the caller can add the version leaves to each
|
|
2475
|
+
// vulnerability's product_status.known_affected.
|
|
2476
|
+
const cveProductIds = {};
|
|
2477
|
+
for (const [cveId, keys] of cveLeaves.entries()) {
|
|
2478
|
+
const pids = [];
|
|
2479
|
+
for (const k of keys) { const pid = leafKeyToPid.get(k); if (pid) pids.push(pid); }
|
|
2480
|
+
if (pids.length) cveProductIds[cveId] = pids.sort();
|
|
2481
|
+
}
|
|
2482
|
+
return { branches, productIds, cveProductIds };
|
|
2442
2483
|
}
|
|
2443
2484
|
|
|
2444
2485
|
// Slugify a string into a URN-safe segment (RFC 8141 NSS). Empty input →
|
|
@@ -2545,6 +2586,24 @@ function sarifLocationsForIndicator(playbook, indicator) {
|
|
|
2545
2586
|
return [{ physicalLocation: { artifactLocation: { uri: candidates[0] } } }];
|
|
2546
2587
|
}
|
|
2547
2588
|
|
|
2589
|
+
// Locations for a finding-class SARIF result, with a guaranteed non-empty
|
|
2590
|
+
// fallback. sarifLocationsForIndicator returns a PHYSICAL location only when the
|
|
2591
|
+
// agent supplied evidence_locations or the playbook's look-artifact source is a
|
|
2592
|
+
// bare path token; the dominant catalog shape is a prose / glob / shell-command
|
|
2593
|
+
// source (which carries whitespace and is rejected by looksLikePath), so the
|
|
2594
|
+
// physical fallback is null for ~most playbooks. A SARIF result with no
|
|
2595
|
+
// `locations[]` is silently DROPPED by GitHub Code Scanning — so a result with
|
|
2596
|
+
// no concrete file still gets a `logicalLocations` entry naming its rule, which
|
|
2597
|
+
// is SARIF-conformant (§3.33), keeps the finding attributable + visible in the
|
|
2598
|
+
// alerts list and in SARIF viewers, and is honest (there is no physical file to
|
|
2599
|
+
// point at when the agent supplied no evidence location). Physical location is
|
|
2600
|
+
// always preferred when available.
|
|
2601
|
+
function sarifResultLocations(playbook, indicator, fqRuleId) {
|
|
2602
|
+
const phys = sarifLocationsForIndicator(playbook, indicator);
|
|
2603
|
+
if (phys && phys.length) return phys;
|
|
2604
|
+
return [{ logicalLocations: [{ name: fqRuleId, fullyQualifiedName: fqRuleId, kind: 'rule' }] }];
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2548
2607
|
// Resolve the package version once per process so CSAF tracking.generator
|
|
2549
2608
|
// can name the engine that emitted the advisory. Best-effort read — bundle
|
|
2550
2609
|
// emission must not crash if package.json is missing (e.g. exotic install).
|
|
@@ -2783,6 +2842,11 @@ function buildEvidenceBundle(format, playbook, analyze, validate, agentSignals,
|
|
|
2783
2842
|
};
|
|
2784
2843
|
const CSAF_CVE_RE = /^CVE-\d{4}-\d{4,}$/;
|
|
2785
2844
|
|
|
2845
|
+
// Build the product-tree branches up front so each CVE's per-version CSAFPID
|
|
2846
|
+
// leaves can be bound into its product_status.known_affected (and the same
|
|
2847
|
+
// tree reused for product_tree below — buildCsafBranches is not re-run).
|
|
2848
|
+
const csafProductTree = buildCsafBranches(analyze.matched_cves || [], runOpts);
|
|
2849
|
+
|
|
2786
2850
|
const cveVulns = analyze.matched_cves.map(c => {
|
|
2787
2851
|
const isFixed = c.vex_status === 'fixed';
|
|
2788
2852
|
const remediations = [{
|
|
@@ -2867,7 +2931,17 @@ function buildEvidenceBundle(format, playbook, analyze, validate, agentSignals,
|
|
|
2867
2931
|
scores,
|
|
2868
2932
|
threats: c.active_exploitation === 'confirmed' ? [{ category: 'exploit_status', details: `Active exploitation confirmed${c.cisa_kev ? ' (CISA KEV)' : ''}.` }] : [],
|
|
2869
2933
|
remediations,
|
|
2870
|
-
|
|
2934
|
+
// Bind this CVE's per-version CSAFPID leaves (from the product tree) into
|
|
2935
|
+
// known_affected, so a CSAF consumer correlating product_status back to
|
|
2936
|
+
// the branches tree resolves the real affected versions, not only the
|
|
2937
|
+
// opaque synthetic product. The leaves are parsed from affected_products
|
|
2938
|
+
// / affected_versions — VULNERABLE version ranges — so they belong ONLY
|
|
2939
|
+
// under known_affected. The VEX-fixed disposition keeps just the synthetic
|
|
2940
|
+
// target product under `fixed`; adding affected ranges there would
|
|
2941
|
+
// mislabel vulnerable versions as fixed releases.
|
|
2942
|
+
product_status: isFixed
|
|
2943
|
+
? { fixed: [productId] }
|
|
2944
|
+
: { known_affected: [productId, ...(csafProductTree.cveProductIds[c.cve_id] || [])] }
|
|
2871
2945
|
};
|
|
2872
2946
|
// route by id shape.
|
|
2873
2947
|
if (idIsCve) {
|
|
@@ -3054,7 +3128,7 @@ function buildEvidenceBundle(format, playbook, analyze, validate, agentSignals,
|
|
|
3054
3128
|
// from catalog data. CSAF §3.1.5.1 makes branches[] strongly
|
|
3055
3129
|
// recommended because NVD / ENISA / Red Hat dashboards render the
|
|
3056
3130
|
// affected-product list off the branches tree, not full_product_names[].
|
|
3057
|
-
const
|
|
3131
|
+
const branches = csafProductTree.branches;
|
|
3058
3132
|
const tree = { full_product_names: fullProductNames };
|
|
3059
3133
|
if (branches.length > 0) tree.branches = branches;
|
|
3060
3134
|
return tree;
|
|
@@ -3109,7 +3183,6 @@ function buildEvidenceBundle(format, playbook, analyze, validate, agentSignals,
|
|
|
3109
3183
|
// (passing a null indicator skips the per-indicator evidence-locations
|
|
3110
3184
|
// branch). Without any `locations`, GitHub Code Scanning silently DROPS
|
|
3111
3185
|
// these results — the highest-severity result class would never surface.
|
|
3112
|
-
const cveFallbackLocs = sarifLocationsForIndicator(playbook, null);
|
|
3113
3186
|
const cveResults = analyze.matched_cves.map(c => {
|
|
3114
3187
|
const result = {
|
|
3115
3188
|
ruleId: `${rulePrefix}${c.cve_id}`,
|
|
@@ -3125,12 +3198,15 @@ function buildEvidenceBundle(format, playbook, analyze, validate, agentSignals,
|
|
|
3125
3198
|
blast_radius_score: analyze.blast_radius_score,
|
|
3126
3199
|
}),
|
|
3127
3200
|
};
|
|
3128
|
-
|
|
3201
|
+
// Always carry a location (physical when known, else a rule-scoped
|
|
3202
|
+
// logicalLocations fallback) so GitHub Code Scanning does not drop the
|
|
3203
|
+
// highest-severity result class.
|
|
3204
|
+
result.locations = sarifResultLocations(playbook, null, result.ruleId);
|
|
3129
3205
|
return result;
|
|
3130
3206
|
});
|
|
3131
3207
|
const indicatorHits = (analyze._detect_indicators || []).filter(i => i.verdict === 'hit');
|
|
3132
3208
|
const indicatorResults = indicatorHits.map(i => {
|
|
3133
|
-
const locs =
|
|
3209
|
+
const locs = sarifResultLocations(playbook, i, `${rulePrefix}${i.id}`);
|
|
3134
3210
|
const result = {
|
|
3135
3211
|
ruleId: `${rulePrefix}${i.id}`,
|
|
3136
3212
|
level: i.deterministic ? 'error' : (i.confidence === 'high' ? 'warning' : 'note'),
|
|
@@ -3143,7 +3219,7 @@ function buildEvidenceBundle(format, playbook, analyze, validate, agentSignals,
|
|
|
3143
3219
|
attack_ref: i.attack_ref,
|
|
3144
3220
|
}),
|
|
3145
3221
|
};
|
|
3146
|
-
|
|
3222
|
+
result.locations = locs; // always present (physical or logical fallback)
|
|
3147
3223
|
return result;
|
|
3148
3224
|
});
|
|
3149
3225
|
const gapResults = (analyze.framework_gap_mapping || []).map((g, idx) => ({
|
package/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "exceptd-security",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.16",
|
|
4
4
|
"description": "AI security skills grounded in mid-2026 threat reality, not stale framework documentation",
|
|
5
5
|
"homepage": "https://exceptd.com",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
],
|
|
58
58
|
"last_threat_review": "2026-05-15",
|
|
59
59
|
"signature": "0H+JfyUVmo/pVFEi5rLENATHjlukPVUqnOWmNPEH77wm8svKGK0aNJ46k6QU5GdHb8c9X9pVJKiuhON6AxDjDw==",
|
|
60
|
-
"signed_at": "2026-06-
|
|
60
|
+
"signed_at": "2026-06-22T17:11:02.747Z",
|
|
61
61
|
"cwe_refs": [
|
|
62
62
|
"CWE-125",
|
|
63
63
|
"CWE-362",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
],
|
|
134
134
|
"last_threat_review": "2026-06-10",
|
|
135
135
|
"signature": "WfqxU2x/feWgatYrCeO9PD3dIY0FAfs4nkVdQRac4fg5BDQPG/vhzhvYVN6Mg11oITACghbPOtZXvS37sACsCA==",
|
|
136
|
-
"signed_at": "2026-06-
|
|
136
|
+
"signed_at": "2026-06-22T17:11:02.749Z",
|
|
137
137
|
"cwe_refs": [
|
|
138
138
|
"CWE-1039",
|
|
139
139
|
"CWE-1426",
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
],
|
|
216
216
|
"last_threat_review": "2026-06-10",
|
|
217
217
|
"signature": "9bNOW4MzmUlFgkXH5tIZkq8YpzhMM+r8YVcNEM39kdEZwfRNG4Bj+Dgr7v4Qgp9D4q7hGNFpK0ywX+dPd3VWAg==",
|
|
218
|
-
"signed_at": "2026-06-
|
|
218
|
+
"signed_at": "2026-06-22T17:11:02.751Z",
|
|
219
219
|
"cwe_refs": [
|
|
220
220
|
"CWE-22",
|
|
221
221
|
"CWE-345",
|
|
@@ -269,7 +269,7 @@
|
|
|
269
269
|
"framework_gaps": [],
|
|
270
270
|
"last_threat_review": "2026-06-10",
|
|
271
271
|
"signature": "5A08+nAu5jwNQ1+vGbFgFAJA/kYD3oiaevhCxT4/2FeW++F070Pm4MD1+oXdv8R2DbtYr+7yXnCGM7UbUPR2AA==",
|
|
272
|
-
"signed_at": "2026-06-
|
|
272
|
+
"signed_at": "2026-06-22T17:11:02.752Z"
|
|
273
273
|
},
|
|
274
274
|
{
|
|
275
275
|
"name": "compliance-theater",
|
|
@@ -301,7 +301,7 @@
|
|
|
301
301
|
],
|
|
302
302
|
"last_threat_review": "2026-06-10",
|
|
303
303
|
"signature": "RCgbI0sMNTKAscXUtrVU25u7OuE64uQvO5JKsB8vIJFWguvT6nZyD7euKuIxIzYhLTyHBiD7Rhp70btlK+JkCg==",
|
|
304
|
-
"signed_at": "2026-06-
|
|
304
|
+
"signed_at": "2026-06-22T17:11:02.753Z"
|
|
305
305
|
},
|
|
306
306
|
{
|
|
307
307
|
"name": "exploit-scoring",
|
|
@@ -332,7 +332,7 @@
|
|
|
332
332
|
],
|
|
333
333
|
"last_threat_review": "2026-06-10",
|
|
334
334
|
"signature": "JJrs+B22/hYxvdYs+abmoire5PbQXPb2uVYyjInZ3UbT8gEjs/5SyfGKx7z86jbtvB3ItApQVAx1AuseIgdyAQ==",
|
|
335
|
-
"signed_at": "2026-06-
|
|
335
|
+
"signed_at": "2026-06-22T17:11:02.754Z"
|
|
336
336
|
},
|
|
337
337
|
{
|
|
338
338
|
"name": "rag-pipeline-security",
|
|
@@ -374,7 +374,7 @@
|
|
|
374
374
|
],
|
|
375
375
|
"last_threat_review": "2026-06-10",
|
|
376
376
|
"signature": "Z6WbTqG98bQVRd6+kXDb6xIEe0ZryAeGxVSuKKxdK1PoZqew7NJcMsa6sJVSq+0r7KMsFwfTEdKorp6UDdhpCA==",
|
|
377
|
-
"signed_at": "2026-06-
|
|
377
|
+
"signed_at": "2026-06-22T17:11:02.755Z",
|
|
378
378
|
"cwe_refs": [
|
|
379
379
|
"CWE-1395",
|
|
380
380
|
"CWE-1426"
|
|
@@ -441,7 +441,7 @@
|
|
|
441
441
|
],
|
|
442
442
|
"last_threat_review": "2026-06-10",
|
|
443
443
|
"signature": "DLKcrgon+MZrqmivlFLBH4vlzZbJSW1531RsYDm9/KdW2CgcUUHwNMSzAfU1mAsFwFkAHjy/a8e1FbS9msTvDA==",
|
|
444
|
-
"signed_at": "2026-06-
|
|
444
|
+
"signed_at": "2026-06-22T17:11:02.756Z",
|
|
445
445
|
"cwe_refs": [
|
|
446
446
|
"CWE-918"
|
|
447
447
|
],
|
|
@@ -482,7 +482,7 @@
|
|
|
482
482
|
"framework_gaps": [],
|
|
483
483
|
"last_threat_review": "2026-06-10",
|
|
484
484
|
"signature": "eWCOD+mR1c6B8vKDBot8y8UkQrKPCIEBHU3JRQET9xZnYGx8hrOyeRUElcKqCO5aG/2LISs9Atg1H+ehWDNbCw==",
|
|
485
|
-
"signed_at": "2026-06-
|
|
485
|
+
"signed_at": "2026-06-22T17:11:02.757Z",
|
|
486
486
|
"cwe_refs": [
|
|
487
487
|
"CWE-1188"
|
|
488
488
|
],
|
|
@@ -517,7 +517,7 @@
|
|
|
517
517
|
"framework_gaps": [],
|
|
518
518
|
"last_threat_review": "2026-06-10",
|
|
519
519
|
"signature": "kZca725/+BFr1mpxL29+cGzjqsiYhChWScf7VjU6vCTBZrmCps6W9gYYjf4lVORXaM4DAg3UVBOXyhpTst0rAw==",
|
|
520
|
-
"signed_at": "2026-06-
|
|
520
|
+
"signed_at": "2026-06-22T17:11:02.758Z",
|
|
521
521
|
"forward_watch": [
|
|
522
522
|
"New AI attack classes as ATLAS v6 publishes",
|
|
523
523
|
"Post-quantum adversary capability timeline",
|
|
@@ -557,7 +557,7 @@
|
|
|
557
557
|
"framework_gaps": [],
|
|
558
558
|
"last_threat_review": "2026-05-01",
|
|
559
559
|
"signature": "b5miTiY0cnxETd2btxorfZBdJKt/fLnQx20sGYUb9zEqGqtm0LMLpghkW68j4/9k48KNyuGMtNWiKTSnodUGBw==",
|
|
560
|
-
"signed_at": "2026-06-
|
|
560
|
+
"signed_at": "2026-06-22T17:11:02.759Z"
|
|
561
561
|
},
|
|
562
562
|
{
|
|
563
563
|
"name": "zeroday-gap-learn",
|
|
@@ -584,7 +584,7 @@
|
|
|
584
584
|
"framework_gaps": [],
|
|
585
585
|
"last_threat_review": "2026-06-10",
|
|
586
586
|
"signature": "NVBY4I5a+v2/nUeCYcy3LLVKk3Tg9gmz+sCKyvnf8t2fXMNSIGtoy+P8K4Gfos1rGzRRMaU01V7L4kh/IQ8UBQ==",
|
|
587
|
-
"signed_at": "2026-06-
|
|
587
|
+
"signed_at": "2026-06-22T17:11:02.760Z",
|
|
588
588
|
"forward_watch": [
|
|
589
589
|
"New CISA KEV entries",
|
|
590
590
|
"New ATLAS TTP additions in each ATLAS release",
|
|
@@ -652,7 +652,7 @@
|
|
|
652
652
|
],
|
|
653
653
|
"last_threat_review": "2026-06-10",
|
|
654
654
|
"signature": "U54OxIjPT+W9yafjpeFgY7klXMltLYBuSCtu/AAlXxOIPehJrbf/vbGgnBn58nqOd7RjoKjmKz9WQs4DMqWcDw==",
|
|
655
|
-
"signed_at": "2026-06-
|
|
655
|
+
"signed_at": "2026-06-22T17:11:02.762Z",
|
|
656
656
|
"cwe_refs": [
|
|
657
657
|
"CWE-327"
|
|
658
658
|
],
|
|
@@ -702,7 +702,7 @@
|
|
|
702
702
|
],
|
|
703
703
|
"last_threat_review": "2026-06-10",
|
|
704
704
|
"signature": "QsJMwvnUJXHwoBPJ4BiUx3FO9giXfos/sMbx5tyO83AJ2JxdVskeC6g/WDfO+rVkWNXRgWi4h1eSYz6T8/tpAg==",
|
|
705
|
-
"signed_at": "2026-06-
|
|
705
|
+
"signed_at": "2026-06-22T17:11:02.763Z"
|
|
706
706
|
},
|
|
707
707
|
{
|
|
708
708
|
"name": "security-maturity-tiers",
|
|
@@ -740,7 +740,7 @@
|
|
|
740
740
|
],
|
|
741
741
|
"last_threat_review": "2026-05-01",
|
|
742
742
|
"signature": "8KbLVVPI1QgYa+HAnEYvKf1cXnxQ3zsncqTGrAOrBP4rwUeZsxJm8KyFCwI0XytnZG35PZ830BFlG/okPW3sBQ==",
|
|
743
|
-
"signed_at": "2026-06-
|
|
743
|
+
"signed_at": "2026-06-22T17:11:02.764Z",
|
|
744
744
|
"cwe_refs": [
|
|
745
745
|
"CWE-1188"
|
|
746
746
|
]
|
|
@@ -776,7 +776,7 @@
|
|
|
776
776
|
"framework_gaps": [],
|
|
777
777
|
"last_threat_review": "2026-05-11",
|
|
778
778
|
"signature": "iJWevUBurLvt2v8X+Ch2eHmZkPWpKeAtIpxTIP4MwbUHyco3igDeBywJCyaR2vURYRx8LkzzIMM8DxQM4LAXBQ==",
|
|
779
|
-
"signed_at": "2026-06-
|
|
779
|
+
"signed_at": "2026-06-22T17:11:02.766Z"
|
|
780
780
|
},
|
|
781
781
|
{
|
|
782
782
|
"name": "attack-surface-pentest",
|
|
@@ -852,7 +852,7 @@
|
|
|
852
852
|
"Pwn2Own Berlin 2026 (disclosed 2026-05-14, embargo ends 2026-08-12) — Microsoft Edge 4-bug sandbox escape by Orange Tsai (DEVCORE); forward-watch only (browser sandbox, out of current playbook scope); track Microsoft Edge security advisory and KEV add"
|
|
853
853
|
],
|
|
854
854
|
"signature": "ZnFi+Rk4CWrjFEVU4hC6Q66UbDmndNL/ICLWQNA1TQYFGSTnng+nboM4tfi6h0yMbbDj7dOXYqqeHNK+M5ZiBA==",
|
|
855
|
-
"signed_at": "2026-06-
|
|
855
|
+
"signed_at": "2026-06-22T17:11:02.767Z"
|
|
856
856
|
},
|
|
857
857
|
{
|
|
858
858
|
"name": "fuzz-testing-strategy",
|
|
@@ -913,7 +913,7 @@
|
|
|
913
913
|
"OSS-Fuzz-Gen / AI-assisted harness generation becoming the default expectation for OSS maintainers"
|
|
914
914
|
],
|
|
915
915
|
"signature": "45ICz7vcnmHYE1+RIDv8wQjScKj6p8hqJQ5m6I0tDdKVnGdMXCYIgZnYqFJgHBDXYAXlGx7D7UxhFz6WOCDqAQ==",
|
|
916
|
-
"signed_at": "2026-06-
|
|
916
|
+
"signed_at": "2026-06-22T17:11:02.768Z"
|
|
917
917
|
},
|
|
918
918
|
{
|
|
919
919
|
"name": "dlp-gap-analysis",
|
|
@@ -991,7 +991,7 @@
|
|
|
991
991
|
"Quebec Law 25, India DPDPA, KSA PDPL enforcement actions naming AI-tool prompt data as in-scope personal information"
|
|
992
992
|
],
|
|
993
993
|
"signature": "k6A7QcFEzgGXYWftt/elhQe7kU4F67c0ol3a8DZfj1XW4UrH99SLhPHr6ih3R3EYCl/Ey/zXt/x3a9fDT3RmAw==",
|
|
994
|
-
"signed_at": "2026-06-
|
|
994
|
+
"signed_at": "2026-06-22T17:11:02.770Z"
|
|
995
995
|
},
|
|
996
996
|
{
|
|
997
997
|
"name": "supply-chain-integrity",
|
|
@@ -1075,7 +1075,7 @@
|
|
|
1075
1075
|
"Pwn2Own Berlin 2026 (disclosed 2026-05-14, embargo ends 2026-08-12) — NVIDIA Megatron Bridge path traversal by haehae; AI training-stack file-system trust boundary; track patch and SBOM-attestation impact"
|
|
1076
1076
|
],
|
|
1077
1077
|
"signature": "5shKqNcLC8Obt0EdvKnck8OwWIuRMgZuuZd12pvWqJIltsYMyTrw2M+lgbQfqg3x2KO6qsJljGAhTew5jM58DQ==",
|
|
1078
|
-
"signed_at": "2026-06-
|
|
1078
|
+
"signed_at": "2026-06-22T17:11:02.771Z"
|
|
1079
1079
|
},
|
|
1080
1080
|
{
|
|
1081
1081
|
"name": "defensive-countermeasure-mapping",
|
|
@@ -1132,7 +1132,7 @@
|
|
|
1132
1132
|
],
|
|
1133
1133
|
"last_threat_review": "2026-06-10",
|
|
1134
1134
|
"signature": "lfa5Wgep26mK3o2ZSe5qN2vVxg+xRRURRpmnqP4JdQvvecW3T2+PxHqjT48DegXJHRXJ6DPzyIElFc7no86TAg==",
|
|
1135
|
-
"signed_at": "2026-06-
|
|
1135
|
+
"signed_at": "2026-06-22T17:11:02.772Z"
|
|
1136
1136
|
},
|
|
1137
1137
|
{
|
|
1138
1138
|
"name": "identity-assurance",
|
|
@@ -1206,7 +1206,7 @@
|
|
|
1206
1206
|
],
|
|
1207
1207
|
"last_threat_review": "2026-05-11",
|
|
1208
1208
|
"signature": "UV3458QXSkEpenzrOmdlTTfPHUD4hNyKMDHoeZDq/kiFb4mAG0ghQGTTgI9Ru8cJbSmYM1++m9N5TFIJ6JJPBg==",
|
|
1209
|
-
"signed_at": "2026-06-
|
|
1209
|
+
"signed_at": "2026-06-22T17:11:02.773Z"
|
|
1210
1210
|
},
|
|
1211
1211
|
{
|
|
1212
1212
|
"name": "ot-ics-security",
|
|
@@ -1265,7 +1265,7 @@
|
|
|
1265
1265
|
"d3fend_refs": [],
|
|
1266
1266
|
"last_threat_review": "2026-06-10",
|
|
1267
1267
|
"signature": "afJ00EDXgARQJrbRqN6xe1+E/kbHF7O2fxQFVvrLLXdrKfK86RK/oJU1AwpxX6mclX9f+5ivy6FvFIuRMA4dBQ==",
|
|
1268
|
-
"signed_at": "2026-06-
|
|
1268
|
+
"signed_at": "2026-06-22T17:11:02.774Z"
|
|
1269
1269
|
},
|
|
1270
1270
|
{
|
|
1271
1271
|
"name": "coordinated-vuln-disclosure",
|
|
@@ -1325,7 +1325,7 @@
|
|
|
1325
1325
|
"NYDFS 23 NYCRR 500 amendments potentially adding explicit CVD program requirements"
|
|
1326
1326
|
],
|
|
1327
1327
|
"signature": "VzivMW82mRrG9+07ZX8sj4j9O9YjE/m07m1UHgSwEgex+FLaVPvIj3y1Vk6qeFOvDURmtVaztWlpSlk7iSn0DA==",
|
|
1328
|
-
"signed_at": "2026-06-
|
|
1328
|
+
"signed_at": "2026-06-22T17:11:02.776Z"
|
|
1329
1329
|
},
|
|
1330
1330
|
{
|
|
1331
1331
|
"name": "threat-modeling-methodology",
|
|
@@ -1379,7 +1379,7 @@
|
|
|
1379
1379
|
"PASTA v2 updates incorporating AI/ML application threats"
|
|
1380
1380
|
],
|
|
1381
1381
|
"signature": "Fk5LzzeS/bH5SQJNySgZqSdeQf1udwdRs3FVLwig5kuqyyKkuIJcF4HW+xHF/1e66HR+gjgRUoqWZGsv58lLAg==",
|
|
1382
|
-
"signed_at": "2026-06-
|
|
1382
|
+
"signed_at": "2026-06-22T17:11:02.778Z"
|
|
1383
1383
|
},
|
|
1384
1384
|
{
|
|
1385
1385
|
"name": "webapp-security",
|
|
@@ -1462,7 +1462,7 @@
|
|
|
1462
1462
|
],
|
|
1463
1463
|
"last_threat_review": "2026-06-10",
|
|
1464
1464
|
"signature": "1skHJsPPOIXLQdU5MGHirP/Q07aCYTirtDmfWDO7ZNuto58NlCttW5ZjCpyh37vASlMljIZx0/R+PIl2PfwTBw==",
|
|
1465
|
-
"signed_at": "2026-06-
|
|
1465
|
+
"signed_at": "2026-06-22T17:11:02.778Z",
|
|
1466
1466
|
"forward_watch": [
|
|
1467
1467
|
"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"
|
|
1468
1468
|
]
|
|
@@ -1522,7 +1522,7 @@
|
|
|
1522
1522
|
],
|
|
1523
1523
|
"last_threat_review": "2026-05-15",
|
|
1524
1524
|
"signature": "SBB7c3wNYfIdkyOp4g4nW0WP7xS+YokMzg32aaeJdbf14LTGQRzQUvSqb2TCj2HFUSHESOyKT1JpkAfyHLSQBQ==",
|
|
1525
|
-
"signed_at": "2026-06-
|
|
1525
|
+
"signed_at": "2026-06-22T17:11:02.780Z"
|
|
1526
1526
|
},
|
|
1527
1527
|
{
|
|
1528
1528
|
"name": "sector-healthcare",
|
|
@@ -1589,7 +1589,7 @@
|
|
|
1589
1589
|
],
|
|
1590
1590
|
"last_threat_review": "2026-06-10",
|
|
1591
1591
|
"signature": "yyAGG3nUC6/XWQGRF2ufzILfiJitMFczqWNY83lZShCgYSxfFCul0UsICClOc7Xjw76052uydm8kLH9gIzhsAg==",
|
|
1592
|
-
"signed_at": "2026-06-
|
|
1592
|
+
"signed_at": "2026-06-22T17:11:02.781Z"
|
|
1593
1593
|
},
|
|
1594
1594
|
{
|
|
1595
1595
|
"name": "sector-financial",
|
|
@@ -1678,7 +1678,7 @@
|
|
|
1678
1678
|
"TIBER-EU framework v2.0 alignment with DORA TLPT RTS (JC 2024/40); cross-recognition with CBEST and iCAST"
|
|
1679
1679
|
],
|
|
1680
1680
|
"signature": "/+df91Qhl1TIxEAqzgqB7+YJ6mneX6Dif+h6RaCbxOLGE6KRTFst1Q/Fu5SStt8Zx5JI62bkQ2BBrNOKfUlPBg==",
|
|
1681
|
-
"signed_at": "2026-06-
|
|
1681
|
+
"signed_at": "2026-06-22T17:11:02.782Z"
|
|
1682
1682
|
},
|
|
1683
1683
|
{
|
|
1684
1684
|
"name": "sector-federal-government",
|
|
@@ -1755,7 +1755,7 @@
|
|
|
1755
1755
|
"Australia PSPF 2024 revision and ISM quarterly updates — track for Essential Eight Maturity Level requirements for federal entities"
|
|
1756
1756
|
],
|
|
1757
1757
|
"signature": "k6MAPS8HJivu0DNwC1azPvyKeig2xLGz/hcqYd8T+s5GvIypPGfkeYRRKmdqMgHUe24f7bQeRZ7AxcQ9Bi6SCg==",
|
|
1758
|
-
"signed_at": "2026-06-
|
|
1758
|
+
"signed_at": "2026-06-22T17:11:02.783Z"
|
|
1759
1759
|
},
|
|
1760
1760
|
{
|
|
1761
1761
|
"name": "sector-energy",
|
|
@@ -1829,7 +1829,7 @@
|
|
|
1829
1829
|
"ICS-CERT advisory feed (https://www.cisa.gov/news-events/cybersecurity-advisories/ics-advisories) for vendor CVEs in Siemens, Rockwell, Schneider Electric, ABB, GE Vernova, Hitachi Energy, AVEVA / OSIsoft PI"
|
|
1830
1830
|
],
|
|
1831
1831
|
"signature": "IYKXn009jfhpKdQKiGB4xb7VgxsJXa6PZawoguP42khU6S/TTemp/YsK1YQCUyabE+2biElL/PP1Hi8zCkSSBw==",
|
|
1832
|
-
"signed_at": "2026-06-
|
|
1832
|
+
"signed_at": "2026-06-22T17:11:02.785Z"
|
|
1833
1833
|
},
|
|
1834
1834
|
{
|
|
1835
1835
|
"name": "sector-telecom",
|
|
@@ -1915,7 +1915,7 @@
|
|
|
1915
1915
|
"O-RAN SFG / WG11 security specifications"
|
|
1916
1916
|
],
|
|
1917
1917
|
"signature": "NAtyzfLPXlUuB78Snb9nWmbZalC1CNlIYN9rYhdEmtB/xQGC6vVnThgrEAHlm7v/jMCFuknvEpUHKdscUnUADw==",
|
|
1918
|
-
"signed_at": "2026-06-
|
|
1918
|
+
"signed_at": "2026-06-22T17:11:02.786Z"
|
|
1919
1919
|
},
|
|
1920
1920
|
{
|
|
1921
1921
|
"name": "api-security",
|
|
@@ -1994,7 +1994,7 @@
|
|
|
1994
1994
|
],
|
|
1995
1995
|
"last_threat_review": "2026-06-10",
|
|
1996
1996
|
"signature": "HUjhPGpZeZeVi1nzBIsEAYh18x5ltlIXnt1yQ5YKz+jC2Dvxw7vV/Clx1/1gDBLAuBvRW9wcNtDr4c0RxhfGDQ==",
|
|
1997
|
-
"signed_at": "2026-06-
|
|
1997
|
+
"signed_at": "2026-06-22T17:11:02.789Z",
|
|
1998
1998
|
"forward_watch": [
|
|
1999
1999
|
"NGINX Rift CVE-2026-42945 (disclosed 2026-05-13, source depthfirst) — KEV-watch predicted CISA KEV listing by 2026-05-29; track for active-exploitation confirmation and patch advisory affecting API gateway / reverse-proxy deployments",
|
|
2000
2000
|
"Pwn2Own Berlin 2026 (disclosed 2026-05-14, embargo ends 2026-08-12) — LiteLLM 3-bug SSRF + Code Injection chain by k3vg3n; LLM-proxy API surface; track upstream patch and CVE assignments",
|
|
@@ -2089,7 +2089,7 @@
|
|
|
2089
2089
|
"CISA KEV additions for cloud-control-plane CVEs (IMDSv1 abuses, federation token mishandling, cross-tenant boundary failures); CISA Cybersecurity Advisories for cross-cloud advisories"
|
|
2090
2090
|
],
|
|
2091
2091
|
"signature": "xa1kr/92/0fBds7LVtRy9aCM2tQRWAfNSFoC6ygbOU7QjamUo8Wt2h2n9W+nZT34STN3woYhXqtfmm8NSjXdBQ==",
|
|
2092
|
-
"signed_at": "2026-06-
|
|
2092
|
+
"signed_at": "2026-06-22T17:11:02.790Z"
|
|
2093
2093
|
},
|
|
2094
2094
|
{
|
|
2095
2095
|
"name": "container-runtime-security",
|
|
@@ -2161,7 +2161,7 @@
|
|
|
2161
2161
|
],
|
|
2162
2162
|
"last_threat_review": "2026-06-10",
|
|
2163
2163
|
"signature": "60hyXAiYfY9lI+EpHG3iFFxa+oF5n71c0tTMa6iXFLNjBJKPevTsdNgQlQsBEnmRJ+dWtOjb/GNBW1KiBx4XAQ==",
|
|
2164
|
-
"signed_at": "2026-06-
|
|
2164
|
+
"signed_at": "2026-06-22T17:11:02.791Z",
|
|
2165
2165
|
"forward_watch": [
|
|
2166
2166
|
"Pwn2Own Berlin 2026 (disclosed 2026-05-14, embargo ends 2026-08-12) — NVIDIA Container Toolkit container escape ($50K award) by chompie / IBM X-Force XOR; high-severity container/hypervisor boundary break; track patch and KEV add post-embargo"
|
|
2167
2167
|
]
|
|
@@ -2242,7 +2242,7 @@
|
|
|
2242
2242
|
"MITRE ATLAS v2026.05 (released May 2026) shipped the AML.T0010 sub-technique expansion this forecast tracked plus new techniques (\"Publish Poisoned AI Agent Tool\", \"Escape to Host\"); inventory now 16 tactics, 84 techniques, 56 sub-techniques. Forward watch: subsequent ATLAS minor and major releases — track next-cadence updates to agentic-AI TTPs and MLOps-pipeline-specific techniques"
|
|
2243
2243
|
],
|
|
2244
2244
|
"signature": "IEECw5lO6ZdpkE/j7Hv6/3Jg2vj9fpXlozY+h85Hrn9QYOJuI0gfBjHoBEchJ2GUTmPwUKoiBoI72PBAQw9RCQ==",
|
|
2245
|
-
"signed_at": "2026-06-
|
|
2245
|
+
"signed_at": "2026-06-22T17:11:02.793Z"
|
|
2246
2246
|
},
|
|
2247
2247
|
{
|
|
2248
2248
|
"name": "incident-response-playbook",
|
|
@@ -2316,7 +2316,7 @@
|
|
|
2316
2316
|
"NYDFS 23 NYCRR 500.17 amendments tightening ransom-payment 24h disclosure operationalization"
|
|
2317
2317
|
],
|
|
2318
2318
|
"signature": "pN1Qa5NRyNJ6h0pmbbqpy3xWdkMANDMUbBst5SKR5fmmqMFopmyrzwIGagiiNgqxjjCunj9J9Wbzs1sL48sMCQ==",
|
|
2319
|
-
"signed_at": "2026-06-
|
|
2319
|
+
"signed_at": "2026-06-22T17:11:02.795Z"
|
|
2320
2320
|
},
|
|
2321
2321
|
{
|
|
2322
2322
|
"name": "ransomware-response",
|
|
@@ -2396,7 +2396,7 @@
|
|
|
2396
2396
|
],
|
|
2397
2397
|
"last_threat_review": "2026-06-10",
|
|
2398
2398
|
"signature": "sXPA1lvWvZpf5sHxZXRkO0Kcs6gnXiYq0mWA53y1HeBwQGJ+viSPMt5IMobkjd5qLFYchg0CpW/nBUIvUE6/DA==",
|
|
2399
|
-
"signed_at": "2026-06-
|
|
2399
|
+
"signed_at": "2026-06-22T17:11:02.796Z"
|
|
2400
2400
|
},
|
|
2401
2401
|
{
|
|
2402
2402
|
"name": "email-security-anti-phishing",
|
|
@@ -2464,7 +2464,7 @@
|
|
|
2464
2464
|
],
|
|
2465
2465
|
"last_threat_review": "2026-05-18",
|
|
2466
2466
|
"signature": "FVBn4ex2qPIo9SHMVJ6tntoz4tVwjbIq3m6wDjjZyv2JODlS+90GBYCOkNamxxkmw/6de6SMs0YHQiF/xjo/DQ==",
|
|
2467
|
-
"signed_at": "2026-06-
|
|
2467
|
+
"signed_at": "2026-06-22T17:11:02.797Z"
|
|
2468
2468
|
},
|
|
2469
2469
|
{
|
|
2470
2470
|
"name": "age-gates-child-safety",
|
|
@@ -2539,7 +2539,7 @@
|
|
|
2539
2539
|
"US state adult-site age-verification laws — 19+ states by mid-2026 (TX HB 18 upheld by SCOTUS June 2025 in Free Speech Coalition v. Paxton); track ongoing challenges in remaining states"
|
|
2540
2540
|
],
|
|
2541
2541
|
"signature": "7Wdii9uwYmDrzQohoWRWDa5A4aDRKOmdLPq5Jsql86O0Gm7pQANnj9tX+cHpQcQ/Ui8VLuNVP8UFdKxxHeDnBg==",
|
|
2542
|
-
"signed_at": "2026-06-
|
|
2542
|
+
"signed_at": "2026-06-22T17:11:02.799Z"
|
|
2543
2543
|
},
|
|
2544
2544
|
{
|
|
2545
2545
|
"name": "cloud-iam-incident",
|
|
@@ -2619,7 +2619,7 @@
|
|
|
2619
2619
|
],
|
|
2620
2620
|
"last_threat_review": "2026-05-15",
|
|
2621
2621
|
"signature": "r9ii4nb3HJELdtKCGF5qy9PHOiot3GC24yfxfGAKlLENHkdRvRkvvL99eV/6RXyfUaMyrnc2Te8tPQcNu5bsDg==",
|
|
2622
|
-
"signed_at": "2026-06-
|
|
2622
|
+
"signed_at": "2026-06-22T17:11:02.800Z",
|
|
2623
2623
|
"forward_watch": [
|
|
2624
2624
|
"AWS IAM Identity Center session-policy refresh and step-up-on-admin enforcement (anticipated 2026-H2 release)",
|
|
2625
2625
|
"GCP Workload Identity Federation principal-set attribute mapping tightening (post-2026 Q3 Federation hardening guide)",
|
|
@@ -2713,7 +2713,7 @@
|
|
|
2713
2713
|
],
|
|
2714
2714
|
"last_threat_review": "2026-05-15",
|
|
2715
2715
|
"signature": "9mfDtMApMAg9V/lmwpniNxo/6gNZoOEoYDfyFvyWvKrPMtc7H9F8uz06FVoARe/J49saAKTVXOurNE1D/KtpCQ==",
|
|
2716
|
-
"signed_at": "2026-06-
|
|
2716
|
+
"signed_at": "2026-06-22T17:11:02.801Z",
|
|
2717
2717
|
"forward_watch": [
|
|
2718
2718
|
"Entra ID conditional access evolution post-Midnight Blizzard — Microsoft's 2025-2026 commitments on legacy-tenant MFA enforcement and OAuth-app consent gating",
|
|
2719
2719
|
"Okta IPSIE (Interoperability Profile for Secure Identity in the Enterprise) OpenID Foundation working-group output and adoption timeline",
|
|
@@ -2785,7 +2785,7 @@
|
|
|
2785
2785
|
"d3fend_refs": [],
|
|
2786
2786
|
"last_threat_review": "2026-06-02",
|
|
2787
2787
|
"signature": "dOFgANMtHm64uSFRjMfeA0fWZS9ISwMTt59I2CbjaF1PgTtbtb8yg/f+3pC4eXcXIET0KPGxRRmENycfIz3rAw==",
|
|
2788
|
-
"signed_at": "2026-06-
|
|
2788
|
+
"signed_at": "2026-06-22T17:11:02.803Z"
|
|
2789
2789
|
},
|
|
2790
2790
|
{
|
|
2791
2791
|
"name": "mail-server-hardening",
|
|
@@ -2844,7 +2844,7 @@
|
|
|
2844
2844
|
"d3fend_refs": [],
|
|
2845
2845
|
"last_threat_review": "2026-06-02",
|
|
2846
2846
|
"signature": "5x8RGzKo/T2IbYnFkYMZs16ThD9a5FEdrKHsnwvtMuGxdyyfZsKNIJVWw2I8O0um0UOXwwkl17Z3zhch26ymCQ==",
|
|
2847
|
-
"signed_at": "2026-06-
|
|
2847
|
+
"signed_at": "2026-06-22T17:11:02.803Z"
|
|
2848
2848
|
},
|
|
2849
2849
|
{
|
|
2850
2850
|
"name": "network-trust",
|
|
@@ -2900,7 +2900,7 @@
|
|
|
2900
2900
|
"d3fend_refs": [],
|
|
2901
2901
|
"last_threat_review": "2026-06-02",
|
|
2902
2902
|
"signature": "C/RdmnGjXKreKiGkwJfUESIxUwQzisGJ9A7KBdE9cBRBHBYHkAcScV89L+Z3kOG032Qax6LeIQai7Lr3nrQBCA==",
|
|
2903
|
-
"signed_at": "2026-06-
|
|
2903
|
+
"signed_at": "2026-06-22T17:11:02.804Z"
|
|
2904
2904
|
},
|
|
2905
2905
|
{
|
|
2906
2906
|
"name": "audit-log-integrity",
|
|
@@ -2955,7 +2955,7 @@
|
|
|
2955
2955
|
"d3fend_refs": [],
|
|
2956
2956
|
"last_threat_review": "2026-06-02",
|
|
2957
2957
|
"signature": "LvUAq+rXCA8PgNy9lTKOmFqa8T9EJg4JEH0axXvEAf9MIHqbR51ergUkFMLaTuvFuApwsPu0r1C30QgScZbiAw==",
|
|
2958
|
-
"signed_at": "2026-06-
|
|
2958
|
+
"signed_at": "2026-06-22T17:11:02.805Z"
|
|
2959
2959
|
},
|
|
2960
2960
|
{
|
|
2961
2961
|
"name": "self-update-integrity",
|
|
@@ -3009,7 +3009,7 @@
|
|
|
3009
3009
|
"d3fend_refs": [],
|
|
3010
3010
|
"last_threat_review": "2026-06-02",
|
|
3011
3011
|
"signature": "BOQZ8G9LdyG/tfpz6rCU4THz5Dq2HGJkUV7uCqSTCMrqnXH6seNXKM41FWawYo0s2VUlXtRgaO7ETp5qgxw+CQ==",
|
|
3012
|
-
"signed_at": "2026-06-
|
|
3012
|
+
"signed_at": "2026-06-22T17:11:02.806Z"
|
|
3013
3013
|
},
|
|
3014
3014
|
{
|
|
3015
3015
|
"name": "multitenancy-isolation",
|
|
@@ -3067,7 +3067,7 @@
|
|
|
3067
3067
|
"d3fend_refs": [],
|
|
3068
3068
|
"last_threat_review": "2026-06-02",
|
|
3069
3069
|
"signature": "bncN0VE4ns0lxtPe48xDR33lerw54BPVkSwX7XlrLQcMHTrV94lmjO8z4ZP4Ko61n+KpuP2SNU8v9JT0bGMmAA==",
|
|
3070
|
-
"signed_at": "2026-06-
|
|
3070
|
+
"signed_at": "2026-06-22T17:11:02.807Z"
|
|
3071
3071
|
},
|
|
3072
3072
|
{
|
|
3073
3073
|
"name": "decompression-dos",
|
|
@@ -3125,7 +3125,7 @@
|
|
|
3125
3125
|
"d3fend_refs": [],
|
|
3126
3126
|
"last_threat_review": "2026-06-02",
|
|
3127
3127
|
"signature": "03i0ZO5ScHIOjGvDKUEsws6m+20fnlJrEhSBtMU7PJzQutrPpmW9gULE0wbayTD5H9URh5nSKZuuVjvjVhZNCg==",
|
|
3128
|
-
"signed_at": "2026-06-
|
|
3128
|
+
"signed_at": "2026-06-22T17:11:02.807Z"
|
|
3129
3129
|
},
|
|
3130
3130
|
{
|
|
3131
3131
|
"name": "log-injection-telemetry",
|
|
@@ -3180,7 +3180,7 @@
|
|
|
3180
3180
|
"d3fend_refs": [],
|
|
3181
3181
|
"last_threat_review": "2026-06-02",
|
|
3182
3182
|
"signature": "twTmA2l+Am2k2PCzB2DNxDQwoYlGopJp/3QgQwBsP7h2LF+uNudisqfuOVV/bYnWfrUhuYZUWbsR3mhzbJCUBw==",
|
|
3183
|
-
"signed_at": "2026-06-
|
|
3183
|
+
"signed_at": "2026-06-22T17:11:02.808Z"
|
|
3184
3184
|
},
|
|
3185
3185
|
{
|
|
3186
3186
|
"name": "privacy-consent-ops",
|
|
@@ -3235,11 +3235,11 @@
|
|
|
3235
3235
|
"d3fend_refs": [],
|
|
3236
3236
|
"last_threat_review": "2026-06-02",
|
|
3237
3237
|
"signature": "0sfKSVrIf555c9bDGkXB96fUClN52fMAMYoQsNQ9eUUSzDiWUwdou+q0gYt43nObtj3m9Yb9X6q3oCXDVMgUDg==",
|
|
3238
|
-
"signed_at": "2026-06-
|
|
3238
|
+
"signed_at": "2026-06-22T17:11:02.809Z"
|
|
3239
3239
|
}
|
|
3240
3240
|
],
|
|
3241
3241
|
"manifest_signature": {
|
|
3242
3242
|
"algorithm": "Ed25519",
|
|
3243
|
-
"signature_base64": "
|
|
3243
|
+
"signature_base64": "n5BM7fxzNpnPWaoIaoKOReV3hdZ6095VSvxHN9nOq5mtPMmQ3RZCkF7DXwHgQYjgTsF4wfc4Qjua3vqNpZ3sAQ=="
|
|
3244
3244
|
}
|
|
3245
3245
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blamejs/exceptd-skills",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.16",
|
|
4
4
|
"description": "AI security skills grounded in mid-2026 threat reality, not stale framework documentation. 51 skills, 11 catalogs (459 CVEs / 181 CWEs / 805 ATT&CK + ICS / 170 ATLAS / 468 D3FEND / 8888 RFCs), 35 jurisdictions, 10-class catalog gap detector + budget gate, real XML parser + canonical-form diff + content-pattern regression detection, Ed25519-signed.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-security",
|
package/sbom.cdx.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.6",
|
|
4
|
-
"serialNumber": "urn:uuid:
|
|
4
|
+
"serialNumber": "urn:uuid:0b112883-81a5-4ba8-8e61-746f26fe6ffc",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
|
-
"timestamp": "
|
|
7
|
+
"timestamp": "2031-11-20T00:04:19.000Z",
|
|
8
8
|
"tools": [
|
|
9
9
|
{
|
|
10
10
|
"vendor": "blamejs",
|
|
11
11
|
"name": "scripts/refresh-sbom.js",
|
|
12
|
-
"version": "0.18.
|
|
12
|
+
"version": "0.18.16"
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"component": {
|
|
16
|
-
"bom-ref": "pkg:npm/@blamejs/exceptd-skills@0.18.
|
|
16
|
+
"bom-ref": "pkg:npm/@blamejs/exceptd-skills@0.18.16",
|
|
17
17
|
"type": "application",
|
|
18
18
|
"name": "@blamejs/exceptd-skills",
|
|
19
|
-
"version": "0.18.
|
|
19
|
+
"version": "0.18.16",
|
|
20
20
|
"description": "AI security skills grounded in mid-2026 threat reality, not stale framework documentation. 51 skills, 11 catalogs (459 CVEs / 181 CWEs / 805 ATT&CK + ICS / 170 ATLAS / 468 D3FEND / 8888 RFCs), 35 jurisdictions, 10-class catalog gap detector + budget gate, real XML parser + canonical-form diff + content-pattern regression detection, Ed25519-signed.",
|
|
21
21
|
"licenses": [
|
|
22
22
|
{
|
|
@@ -25,17 +25,17 @@
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
],
|
|
28
|
-
"purl": "pkg:npm/%40blamejs/exceptd-skills@0.18.
|
|
28
|
+
"purl": "pkg:npm/%40blamejs/exceptd-skills@0.18.16",
|
|
29
29
|
"hashes": [
|
|
30
30
|
{
|
|
31
31
|
"alg": "SHA-256",
|
|
32
|
-
"content": "
|
|
32
|
+
"content": "e9468ce3b3ced06212212f4d673fd48029af7da454f706b27f808087a9dabb59"
|
|
33
33
|
}
|
|
34
34
|
],
|
|
35
35
|
"externalReferences": [
|
|
36
36
|
{
|
|
37
37
|
"type": "distribution",
|
|
38
|
-
"url": "https://www.npmjs.com/package/@blamejs/exceptd-skills/v/0.18.
|
|
38
|
+
"url": "https://www.npmjs.com/package/@blamejs/exceptd-skills/v/0.18.16"
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
"type": "vcs",
|
|
@@ -116,11 +116,11 @@
|
|
|
116
116
|
"hashes": [
|
|
117
117
|
{
|
|
118
118
|
"alg": "SHA-256",
|
|
119
|
-
"content": "
|
|
119
|
+
"content": "5fa37969557300b07eb36f4c82162ffd75f626d93c5b86c25bd6afb0c0c4e196"
|
|
120
120
|
},
|
|
121
121
|
{
|
|
122
122
|
"alg": "SHA3-512",
|
|
123
|
-
"content": "
|
|
123
|
+
"content": "74cc119ea3fafd51b551119855282a14786fd1514ab6a777ceb57e4e352098222840ddbbb5e7eeb1b3ee4b3d5b9e47ada3b34ef85b432922d61d53408ebd3b33"
|
|
124
124
|
}
|
|
125
125
|
]
|
|
126
126
|
},
|
|
@@ -281,11 +281,11 @@
|
|
|
281
281
|
"hashes": [
|
|
282
282
|
{
|
|
283
283
|
"alg": "SHA-256",
|
|
284
|
-
"content": "
|
|
284
|
+
"content": "d2c715002ff57fe0896b994d946a379e2e11258b6df2080c2241247dd9cbe39e"
|
|
285
285
|
},
|
|
286
286
|
{
|
|
287
287
|
"alg": "SHA3-512",
|
|
288
|
-
"content": "
|
|
288
|
+
"content": "1aa590b60e4e66a34e882b216fa1862b83a96260859feea15a5bdb263299486e78cdf17ee79e9529936349ab6fef07a294f19ad765f56481fbb211ccbdea02a9"
|
|
289
289
|
}
|
|
290
290
|
]
|
|
291
291
|
},
|
|
@@ -1466,11 +1466,11 @@
|
|
|
1466
1466
|
"hashes": [
|
|
1467
1467
|
{
|
|
1468
1468
|
"alg": "SHA-256",
|
|
1469
|
-
"content": "
|
|
1469
|
+
"content": "c33e749b67d2d1ff19a4f5e6aac4947c97b9ef03d44f0f273cd44eb7a1a76cd1"
|
|
1470
1470
|
},
|
|
1471
1471
|
{
|
|
1472
1472
|
"alg": "SHA3-512",
|
|
1473
|
-
"content": "
|
|
1473
|
+
"content": "84c2b2d74d4fa8b88430a3c2bb662143bb580c7b7b42f2203a01a1384ad0cada0c51bd45f7d2697ba278715c9fd7ed37f3e1c0a3fcb1d6f4479d43386c285a2a"
|
|
1474
1474
|
}
|
|
1475
1475
|
]
|
|
1476
1476
|
},
|
|
@@ -1901,11 +1901,11 @@
|
|
|
1901
1901
|
"hashes": [
|
|
1902
1902
|
{
|
|
1903
1903
|
"alg": "SHA-256",
|
|
1904
|
-
"content": "
|
|
1904
|
+
"content": "c8376cbda42a9657b6a5d50f75d8c08a0bcab7c8456340042be7998133922ecb"
|
|
1905
1905
|
},
|
|
1906
1906
|
{
|
|
1907
1907
|
"alg": "SHA3-512",
|
|
1908
|
-
"content": "
|
|
1908
|
+
"content": "eb932bc21fa7e5c210f265b6e7a5eaebae58354c5a4f8cd61c66b4e35939c65a02ea9e1d84e0f44975c1e582217a3e8dae2172e1824b26b4f05d2555c54562e2"
|
|
1909
1909
|
}
|
|
1910
1910
|
]
|
|
1911
1911
|
},
|