@blamejs/exceptd-skills 0.15.49 → 0.15.51
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 +15 -4
- package/data/_indexes/_meta.json +10 -10
- package/data/_indexes/activity-feed.json +2 -2
- package/data/_indexes/catalog-summaries.json +6 -6
- package/data/_indexes/chains.json +775 -0
- package/data/_indexes/section-offsets.json +25 -25
- package/data/_indexes/token-budget.json +9 -9
- package/data/attack-techniques.json +30 -9
- package/data/cve-catalog.json +455 -7
- package/data/cwe-catalog.json +15 -5
- package/data/framework-control-gaps.json +29 -10
- package/data/playbooks/sbom.json +60 -1
- package/data/zeroday-lessons.json +251 -1
- package/lib/collectors/scan-excludes.js +1 -1
- package/lib/playbook-runner.js +15 -3
- package/lib/verify.js +1 -0
- package/manifest.json +45 -45
- package/package.json +1 -1
- package/sbom.cdx.json +100 -45
- package/scripts/check-codebase-patterns.js +41 -0
- package/scripts/predeploy.js +1 -1
- package/scripts/release.js +16 -0
- package/skills/supply-chain-integrity/skill.md +2 -0
- package/vendor/blamejs/README.md +1 -0
- package/vendor/blamejs/_PROVENANCE.json +16 -0
- package/vendor/blamejs/codepoint-class.js +262 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.15.51 — 2026-05-30
|
|
4
|
+
|
|
5
|
+
Catalog: three new supply-chain entries. CVE-2022-23812 — the node-ipc "peacenotwar" protestware incident, where a trusted maintainer shipped a geo-targeted file-wiper in the package main module, so `--ignore-scripts` (the usual npm-supply-chain mitigation) does not stop it. TrapDoor — a cross-ecosystem (npm / PyPI / crates.io) credential-stealer campaign whose novel vector plants zero-width-Unicode instructions in `.cursorrules` / `CLAUDE.md` files to subvert AI coding assistants into discovering and exfiltrating local secrets. MOIKA — the catalog's first dependency-confusion entry: public packages published under squatted internal scopes at inflated versions, with a postinstall stager that exfiltrates the full process environment. Each carries its paired zero-day lesson and new framework-lag controls (main-module-payload detection, AI-assistant config-file poisoning detection, internal-scope→registry pinning).
|
|
6
|
+
|
|
7
|
+
Supply-chain playbook: a package-capability taxonomy (network / filesystem / shell / env / eval / install-script / telemetry / native-binary) as a CVE-independent screening lens. Two new detectors flag a dependency that gains a capability across a version bump, and a no-CVE package whose install-script combines with shell / network / env access (the credential-harvesting delivery shape) — both gated by false-positive checks for the build-tooling and native-addon class.
|
|
8
|
+
|
|
9
|
+
## 0.15.50 — 2026-05-30
|
|
10
|
+
|
|
11
|
+
Hardening: `--operator` validation and the operator-text sanitizer now classify and strip Unicode threat codepoints — Trojan-Source bidirectional overrides (CVE-2021-42574), zero-width/invisible marks, C0 controls, and null — through a shared vendored codepoint-threat table, and the `--operator` rejection now names the specific codepoint family (for example "bidirectional-override codepoint") instead of a generic message. Unicode General Category C remains the reject/strip backstop, so the broader control / private-use / unassigned set is still refused.
|
|
12
|
+
|
|
13
|
+
Internal: a new codebase-pattern gate class, `bidi-codepoint-literal`, blocks raw bidi-override / zero-width / null codepoints embedded literally in source (invisible-in-review code reordering — the Trojan-Source class); source must escape them or route through the shared table.
|
|
14
|
+
|
|
3
15
|
## 0.15.49 — 2026-05-30
|
|
4
16
|
|
|
5
17
|
Internal: a new predeploy gate, `scripts/check-codebase-patterns.js`, enforces code-shape bug classes that recurred across releases. It blocks a library-callable function that writes to stdout and then calls `process.exit()` (which truncates buffered output when the stream is piped — the class the v0.15.47 validate-cves fix addressed) and a stale or reason-less `// allow:` suppression marker, and warns on dynamic `RegExp` construction. The flagged `process.exit` sites across the catalog, playbook, package, and vendor validators were converted to the flush-safe `safeExit` form, and the dynamic-`RegExp` sites carry inline justification markers. A companion advisory, wired into the release `prepare` step, flags when the upstream pattern catalog grows a class exceptd hasn't triaged. No change to the shipped CLI surface, catalogs, or skills.
|
package/bin/exceptd.js
CHANGED
|
@@ -63,6 +63,7 @@ const PKG_ROOT = path.resolve(__dirname, "..");
|
|
|
63
63
|
const { EXIT_CODES, listExitCodes } = require(path.join(PKG_ROOT, "lib", "exit-codes.js"));
|
|
64
64
|
const { validateIdComponent } = require(path.join(PKG_ROOT, "lib", "id-validation.js"));
|
|
65
65
|
const { suggestFlag, flagsFor, VERB_FLAG_ALLOWLIST } = require(path.join(PKG_ROOT, "lib", "flag-suggest.js"));
|
|
66
|
+
const codepointClass = require(path.join(PKG_ROOT, "vendor", "blamejs", "codepoint-class.js"));
|
|
66
67
|
|
|
67
68
|
// Union of every flag known to ANY verb. A flag that is valid somewhere but
|
|
68
69
|
// not on the active verb (e.g. `--csaf-status` on `brief`) is cross-verb
|
|
@@ -1524,6 +1525,7 @@ function dispatchPlaybook(cmd, argv) {
|
|
|
1524
1525
|
// Cc / Cf / Co / Cn — bidi overrides (U+202E "RTL OVERRIDE"),
|
|
1525
1526
|
// zero-width joiners (U+200B-D), invisible format chars, private-use
|
|
1526
1527
|
// codepoints, unassigned codepoints. An operator string like
|
|
1528
|
+
// allow:bidi-codepoint-literal — illustrative bidi-forgery example in the --operator reject-path doc comment
|
|
1527
1529
|
// "aliceevilbob" renders as "alicebobevila" in any UI that respects
|
|
1528
1530
|
// bidi — a forgery surface where the attested name looks like Bob but the
|
|
1529
1531
|
// bytes are Alice. Reject anything outside a positive allowlist of
|
|
@@ -1552,18 +1554,27 @@ function dispatchPlaybook(cmd, argv) {
|
|
|
1552
1554
|
);
|
|
1553
1555
|
}
|
|
1554
1556
|
if (/\p{C}/u.test(normalized)) {
|
|
1555
|
-
//
|
|
1556
|
-
//
|
|
1557
|
+
// \p{C} (Cc/Cf/Cs/Co/Cn) is the reject gate — it is strictly broader
|
|
1558
|
+
// than the named family regexes (bidi / C0-control / zero-width / null),
|
|
1559
|
+
// so it stays the backstop and catches the divergent remainder the
|
|
1560
|
+
// family tables miss (U+007F, U+0080-009F, private-use, unassigned).
|
|
1561
|
+
// The vendored codepoint tables only CLASSIFY the first offending
|
|
1562
|
+
// codepoint into a human family name for the hint.
|
|
1557
1563
|
let offending = "";
|
|
1564
|
+
let family = "control / format / private-use / unassigned codepoint";
|
|
1558
1565
|
for (const cp of normalized) {
|
|
1559
1566
|
if (/\p{C}/u.test(cp)) {
|
|
1560
1567
|
offending = "U+" + cp.codePointAt(0).toString(16).toUpperCase().padStart(4, "0");
|
|
1568
|
+
if (codepointClass.BIDI_RE.test(cp)) family = "bidirectional-override codepoint";
|
|
1569
|
+
else if (codepointClass.ZERO_WIDTH_RE.test(cp)) family = "zero-width / invisible codepoint";
|
|
1570
|
+
else if (cp === codepointClass.NULL_BYTE) family = "null byte";
|
|
1571
|
+
else if (codepointClass.C0_CTRL_RE.test(cp)) family = "C0 control character";
|
|
1561
1572
|
break;
|
|
1562
1573
|
}
|
|
1563
1574
|
}
|
|
1564
1575
|
return emitError(
|
|
1565
|
-
`${cmd}: --operator contains a Unicode
|
|
1566
|
-
{ verb: cmd, provided_length: args.operator.length, offending_codepoint: offending },
|
|
1576
|
+
`${cmd}: --operator contains a Unicode ${family} (${offending}). Bidi overrides, zero-width joiners, and format marks corrupt attestation rendering and enable name-forgery. Use printable identifiers only.`,
|
|
1577
|
+
{ verb: cmd, provided_length: args.operator.length, offending_codepoint: offending, offending_family: family },
|
|
1567
1578
|
pretty
|
|
1568
1579
|
);
|
|
1569
1580
|
}
|
package/data/_indexes/_meta.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "1.1.0",
|
|
3
|
-
"generated_at": "2026-05-
|
|
3
|
+
"generated_at": "2026-05-31T03:23:30.384Z",
|
|
4
4
|
"generator": "scripts/build-indexes.js",
|
|
5
5
|
"source_count": 54,
|
|
6
6
|
"source_hashes": {
|
|
7
|
-
"manifest.json": "
|
|
7
|
+
"manifest.json": "26f77d56ab70b31946f08cd83c8cd5fc43e807c77955a0e9d4ae9450d32e29c9",
|
|
8
8
|
"data/atlas-ttps.json": "878b4a08bb73c8d20396d85cf433a88f2bc5e7a8cbf7f6ab773ce7ede0a11251",
|
|
9
|
-
"data/attack-techniques.json": "
|
|
10
|
-
"data/cve-catalog.json": "
|
|
11
|
-
"data/cwe-catalog.json": "
|
|
9
|
+
"data/attack-techniques.json": "318bf8e9c5aee1d0a4a1dc37c4b211f2fbc937bf332a401a22483cc7d0547252",
|
|
10
|
+
"data/cve-catalog.json": "cb5e305b5488a2a02e177f10e913d22f602d6016109f152903093e9614e0b470",
|
|
11
|
+
"data/cwe-catalog.json": "b0e4d8f90b655b2b35b1e91c682ee66f2aa51ae5d38efb14f0e1b77f75ec5f7b",
|
|
12
12
|
"data/d3fend-catalog.json": "9a54bccb9f24f84b32024216cc3f53819a053721ac8ab43c326859e68fc0ffaf",
|
|
13
13
|
"data/dlp-controls.json": "d2406c482dddd30e49203879999dc4b3a7fd4d0494d6a61d86b91ee76415df19",
|
|
14
14
|
"data/exploit-availability.json": "ec2656f0d9a893610e27b43eb6035fe9b18e057c9f6dfaac7e7d4959bbcbb795",
|
|
15
|
-
"data/framework-control-gaps.json": "
|
|
15
|
+
"data/framework-control-gaps.json": "49cfbcaf0f27662db7e12340839c29f05d4ae31bc255dc9fa49ad1b4a45d0fa3",
|
|
16
16
|
"data/global-frameworks.json": "9ba563a85f7f8d6c3c957de64945e20925a89d0ed6ea6fc561cf093811acf558",
|
|
17
17
|
"data/rfc-references.json": "b21d03b948c41bc8a854e2f057948ecf844bd8c105848aeb141d1eadf8192c31",
|
|
18
|
-
"data/zeroday-lessons.json": "
|
|
18
|
+
"data/zeroday-lessons.json": "c7419ef8265a8385ab29e37e3f3237f120dd2fa448692f9dc1aa2fd79339fc76",
|
|
19
19
|
"skills/kernel-lpe-triage/skill.md": "0f79c641cef6e5f4a942eb94f43c460562bf83dfb67ae112d146c39c6b320fb0",
|
|
20
20
|
"skills/ai-attack-surface/skill.md": "2880499993e0e69e3897a9d02b5e83aa0462c86a4dd2c1988b9968e375704a1f",
|
|
21
21
|
"skills/mcp-agent-trust/skill.md": "0752834acde0303d6d1e36be4b320eac3d34fde715bb8d71f3ad9e801d701482",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"skills/attack-surface-pentest/skill.md": "8d1137c3270763f1c90a3fa8c1c19ab5dc769623c1a35d6a71859bdb8cca2a3e",
|
|
36
36
|
"skills/fuzz-testing-strategy/skill.md": "07e2ee5f773a3f0e82bd21b8a7e8cf6d5b1a8bf3ac6f71602f16550561ade553",
|
|
37
37
|
"skills/dlp-gap-analysis/skill.md": "89dedc6c062fa2afd2284e608f4a51effda819e9288fbf38ab16a7891ccd8a10",
|
|
38
|
-
"skills/supply-chain-integrity/skill.md": "
|
|
38
|
+
"skills/supply-chain-integrity/skill.md": "23d15c234afedec011d9c3e588334132373a22d09ef33cd2d943e479c88fcb43",
|
|
39
39
|
"skills/defensive-countermeasure-mapping/skill.md": "212c0c31dcdaf30dfc68d870e43015dc1420674563e47e6cfb7036067a1b8713",
|
|
40
40
|
"skills/identity-assurance/skill.md": "86649aa573bde5b2ef2456a77d2fbfa9d1b623a4ef1326dd7a7ab384d0419307",
|
|
41
41
|
"skills/ot-ics-security/skill.md": "583f758ace33e638ddbbc985eda1ffc711bb040ce24f528d502fc13e5f7bb46e",
|
|
@@ -72,13 +72,13 @@
|
|
|
72
72
|
"dlp_refs": 0
|
|
73
73
|
},
|
|
74
74
|
"trigger_table_entries": 538,
|
|
75
|
-
"chains_cve_entries":
|
|
75
|
+
"chains_cve_entries": 417,
|
|
76
76
|
"chains_cwe_entries": 173,
|
|
77
77
|
"jurisdictions_indexed": 29,
|
|
78
78
|
"handoff_dag_nodes": 42,
|
|
79
79
|
"summary_cards": 42,
|
|
80
80
|
"section_offsets_skills": 42,
|
|
81
|
-
"token_budget_total_approx":
|
|
81
|
+
"token_budget_total_approx": 418794,
|
|
82
82
|
"recipes": 8,
|
|
83
83
|
"jurisdiction_clocks": 29,
|
|
84
84
|
"did_ladders": 8,
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"artifact": "data/cve-catalog.json",
|
|
12
12
|
"path": "data/cve-catalog.json",
|
|
13
13
|
"schema_version": "1.0.0",
|
|
14
|
-
"entry_count":
|
|
14
|
+
"entry_count": 430
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
"date": "2026-05-27",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
"artifact": "data/zeroday-lessons.json",
|
|
166
166
|
"path": "data/zeroday-lessons.json",
|
|
167
167
|
"schema_version": "1.1.0",
|
|
168
|
-
"entry_count":
|
|
168
|
+
"entry_count": 430
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
171
|
"date": "2026-05-17",
|
|
@@ -62,13 +62,13 @@
|
|
|
62
62
|
"rebuild_after_days": 365,
|
|
63
63
|
"note": "Per-entry last_verified governs decay. Skills depending on this catalog must check entry freshness before high-stakes use."
|
|
64
64
|
},
|
|
65
|
-
"entry_count":
|
|
65
|
+
"entry_count": 430,
|
|
66
66
|
"sample_keys": [
|
|
67
|
+
"CVE-2022-23812",
|
|
68
|
+
"MAL-2026-TRAPDOOR-CROSS-ECOSYSTEM",
|
|
69
|
+
"MAL-2026-MOIKA-DEPCONFUSION",
|
|
67
70
|
"CVE-2025-0282",
|
|
68
|
-
"CVE-2025-22457"
|
|
69
|
-
"CVE-2025-31324",
|
|
70
|
-
"CVE-2025-31161",
|
|
71
|
-
"CVE-2025-30066"
|
|
71
|
+
"CVE-2025-22457"
|
|
72
72
|
]
|
|
73
73
|
},
|
|
74
74
|
"cwe-catalog.json": {
|
|
@@ -238,7 +238,7 @@
|
|
|
238
238
|
"rebuild_after_days": 365,
|
|
239
239
|
"note": "Per-entry last_verified governs decay. Skills depending on this catalog must check entry freshness before high-stakes use."
|
|
240
240
|
},
|
|
241
|
-
"entry_count":
|
|
241
|
+
"entry_count": 430,
|
|
242
242
|
"sample_keys": [
|
|
243
243
|
"CVE-2026-31431",
|
|
244
244
|
"CVE-2025-53773",
|