@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/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:9acfa07c-b6cd-4814-91c7-1c28fa9036c5",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
|
-
"timestamp": "
|
|
7
|
+
"timestamp": "2108-04-22T07:45:00.000Z",
|
|
8
8
|
"tools": [
|
|
9
9
|
{
|
|
10
10
|
"vendor": "blamejs",
|
|
11
11
|
"name": "scripts/refresh-sbom.js",
|
|
12
|
-
"version": "0.15.
|
|
12
|
+
"version": "0.15.51"
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"component": {
|
|
16
|
-
"bom-ref": "pkg:npm/@blamejs/exceptd-skills@0.15.
|
|
16
|
+
"bom-ref": "pkg:npm/@blamejs/exceptd-skills@0.15.51",
|
|
17
17
|
"type": "application",
|
|
18
18
|
"name": "@blamejs/exceptd-skills",
|
|
19
|
-
"version": "0.15.
|
|
19
|
+
"version": "0.15.51",
|
|
20
20
|
"description": "AI security skills grounded in mid-2026 threat reality, not stale framework documentation. 42 skills, 11 catalogs (427 CVEs / 173 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.15.
|
|
28
|
+
"purl": "pkg:npm/%40blamejs/exceptd-skills@0.15.51",
|
|
29
29
|
"hashes": [
|
|
30
30
|
{
|
|
31
31
|
"alg": "SHA-256",
|
|
32
|
-
"content": "
|
|
32
|
+
"content": "286ba553798e8b3455fe13a1541b186417e4a817f9c33575e26cf828a1c08d6e"
|
|
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.15.
|
|
38
|
+
"url": "https://www.npmjs.com/package/@blamejs/exceptd-skills/v/0.15.51"
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
"type": "vcs",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
"name": "exceptd:vendor:count",
|
|
73
|
-
"value": "
|
|
73
|
+
"value": "3"
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
"name": "exceptd:vendor:pin",
|
|
@@ -116,11 +116,11 @@
|
|
|
116
116
|
"hashes": [
|
|
117
117
|
{
|
|
118
118
|
"alg": "SHA-256",
|
|
119
|
-
"content": "
|
|
119
|
+
"content": "dc00c4b9ab8c88da642c093ff93db1017413c78cc05b9018466be6631c71fec5"
|
|
120
120
|
},
|
|
121
121
|
{
|
|
122
122
|
"alg": "SHA3-512",
|
|
123
|
-
"content": "
|
|
123
|
+
"content": "b05cb2e274f890263a22f70998d287f96470f83443b891c4a2958a9e053af429d53556495b7e5e427f3892223c3f255917560a3610bdea991e058eaf7cf670de"
|
|
124
124
|
}
|
|
125
125
|
]
|
|
126
126
|
},
|
|
@@ -281,11 +281,11 @@
|
|
|
281
281
|
"hashes": [
|
|
282
282
|
{
|
|
283
283
|
"alg": "SHA-256",
|
|
284
|
-
"content": "
|
|
284
|
+
"content": "cf9b74140298bdee14d4826d11ed9f7d6b1266db8a782d8dce48425e76ec9af5"
|
|
285
285
|
},
|
|
286
286
|
{
|
|
287
287
|
"alg": "SHA3-512",
|
|
288
|
-
"content": "
|
|
288
|
+
"content": "0528bbd4277fe3b8f4cb99eeaf35d5e9f310cfd48a0164fa4e4edb03154f1c7302af7d44617d7b6f1d6ab52e301a7772042e4c609693c49b8ce6eb64991419b9"
|
|
289
289
|
}
|
|
290
290
|
]
|
|
291
291
|
},
|
|
@@ -311,11 +311,11 @@
|
|
|
311
311
|
"hashes": [
|
|
312
312
|
{
|
|
313
313
|
"alg": "SHA-256",
|
|
314
|
-
"content": "
|
|
314
|
+
"content": "318bf8e9c5aee1d0a4a1dc37c4b211f2fbc937bf332a401a22483cc7d0547252"
|
|
315
315
|
},
|
|
316
316
|
{
|
|
317
317
|
"alg": "SHA3-512",
|
|
318
|
-
"content": "
|
|
318
|
+
"content": "d929874af7a8091416f2adc116fcfe98383325c83ece819a3e07320e29b4d8645b27256a662a6fff3267156ff70cfe2f53d7b0a82b5f249902c495f5d668b962"
|
|
319
319
|
}
|
|
320
320
|
]
|
|
321
321
|
},
|
|
@@ -326,11 +326,11 @@
|
|
|
326
326
|
"hashes": [
|
|
327
327
|
{
|
|
328
328
|
"alg": "SHA-256",
|
|
329
|
-
"content": "
|
|
329
|
+
"content": "cb5e305b5488a2a02e177f10e913d22f602d6016109f152903093e9614e0b470"
|
|
330
330
|
},
|
|
331
331
|
{
|
|
332
332
|
"alg": "SHA3-512",
|
|
333
|
-
"content": "
|
|
333
|
+
"content": "a7abc804efd7dfd46056a857ee13e19b8d99cdd46db7390845f4036b1e4b97bce0e00ec3f677322716f6c74b071340561fdf8cfda9b2f5ff3b502353eaf4d135"
|
|
334
334
|
}
|
|
335
335
|
]
|
|
336
336
|
},
|
|
@@ -341,11 +341,11 @@
|
|
|
341
341
|
"hashes": [
|
|
342
342
|
{
|
|
343
343
|
"alg": "SHA-256",
|
|
344
|
-
"content": "
|
|
344
|
+
"content": "b0e4d8f90b655b2b35b1e91c682ee66f2aa51ae5d38efb14f0e1b77f75ec5f7b"
|
|
345
345
|
},
|
|
346
346
|
{
|
|
347
347
|
"alg": "SHA3-512",
|
|
348
|
-
"content": "
|
|
348
|
+
"content": "ac9ca3b420093c62dd5a53b0349f1d5e9f10f90c958d0ab921654bd0bcf674d3aef478fc5bc3d359a224b03cd26b32578fe162f55ba2423c37c0061aaa80c862"
|
|
349
349
|
}
|
|
350
350
|
]
|
|
351
351
|
},
|
|
@@ -401,11 +401,11 @@
|
|
|
401
401
|
"hashes": [
|
|
402
402
|
{
|
|
403
403
|
"alg": "SHA-256",
|
|
404
|
-
"content": "
|
|
404
|
+
"content": "49cfbcaf0f27662db7e12340839c29f05d4ae31bc255dc9fa49ad1b4a45d0fa3"
|
|
405
405
|
},
|
|
406
406
|
{
|
|
407
407
|
"alg": "SHA3-512",
|
|
408
|
-
"content": "
|
|
408
|
+
"content": "677e753faee573812cfcb3b33e351b36430b38d36c409149a471b0561139ba1dccc23f1a15c9b836f0c5c7384abaa5dc7a56b3f0d8c747fc7d5f216f03911028"
|
|
409
409
|
}
|
|
410
410
|
]
|
|
411
411
|
},
|
|
@@ -731,11 +731,11 @@
|
|
|
731
731
|
"hashes": [
|
|
732
732
|
{
|
|
733
733
|
"alg": "SHA-256",
|
|
734
|
-
"content": "
|
|
734
|
+
"content": "c5e35e621cfd1702bd048dca73f0a309323b537aa73680967295a4176da7368b"
|
|
735
735
|
},
|
|
736
736
|
{
|
|
737
737
|
"alg": "SHA3-512",
|
|
738
|
-
"content": "
|
|
738
|
+
"content": "919da50a7973dd8f64cd1088ebbc12ae11800b57dc2a65704d29aa373e63db841d392eee45da2a1cd2cfe6df605252bbbe06e303586ba9ebb6bad7a613031dad"
|
|
739
739
|
}
|
|
740
740
|
]
|
|
741
741
|
},
|
|
@@ -806,11 +806,11 @@
|
|
|
806
806
|
"hashes": [
|
|
807
807
|
{
|
|
808
808
|
"alg": "SHA-256",
|
|
809
|
-
"content": "
|
|
809
|
+
"content": "c7419ef8265a8385ab29e37e3f3237f120dd2fa448692f9dc1aa2fd79339fc76"
|
|
810
810
|
},
|
|
811
811
|
{
|
|
812
812
|
"alg": "SHA3-512",
|
|
813
|
-
"content": "
|
|
813
|
+
"content": "7aea30cb368c94ff5e9fa3d1d6e60a71f81a1c36d5b358310b372b99d1e448ff5c19c34f2fb33316841906e3f988bc305a8c9c158d9fb33c62b91538a56fcde5"
|
|
814
814
|
}
|
|
815
815
|
]
|
|
816
816
|
},
|
|
@@ -1106,11 +1106,11 @@
|
|
|
1106
1106
|
"hashes": [
|
|
1107
1107
|
{
|
|
1108
1108
|
"alg": "SHA-256",
|
|
1109
|
-
"content": "
|
|
1109
|
+
"content": "17c8544a8043fd8a24aa22c1b5c061806983bc896a51b120f1976dea1c770a3d"
|
|
1110
1110
|
},
|
|
1111
1111
|
{
|
|
1112
1112
|
"alg": "SHA3-512",
|
|
1113
|
-
"content": "
|
|
1113
|
+
"content": "fdca23d1585d169fa2dad9be3f840de556b2673fefc6406c4ad0fb6cdf4e85a98103afc125f725c2fb3146fead224e444f963c17e031d6c64581a8552da96eca"
|
|
1114
1114
|
}
|
|
1115
1115
|
]
|
|
1116
1116
|
},
|
|
@@ -1316,11 +1316,11 @@
|
|
|
1316
1316
|
"hashes": [
|
|
1317
1317
|
{
|
|
1318
1318
|
"alg": "SHA-256",
|
|
1319
|
-
"content": "
|
|
1319
|
+
"content": "f9452a58e4916a512b61ac8c6179dff6162f3634cf766b129d521233daec3c0e"
|
|
1320
1320
|
},
|
|
1321
1321
|
{
|
|
1322
1322
|
"alg": "SHA3-512",
|
|
1323
|
-
"content": "
|
|
1323
|
+
"content": "d6ebf5ffca3fee2398034f411eb477d393e8ee8a7f12ed576e72f0e785c42b37e760fb743bf47d0a4c704c71f726ba56e373fbd4149e2750c00ee89e8af74efe"
|
|
1324
1324
|
}
|
|
1325
1325
|
]
|
|
1326
1326
|
},
|
|
@@ -1661,11 +1661,11 @@
|
|
|
1661
1661
|
"hashes": [
|
|
1662
1662
|
{
|
|
1663
1663
|
"alg": "SHA-256",
|
|
1664
|
-
"content": "
|
|
1664
|
+
"content": "484c2c4747699b7a32658126ade2fb498656cde204a8a30efde0730c04305a48"
|
|
1665
1665
|
},
|
|
1666
1666
|
{
|
|
1667
1667
|
"alg": "SHA3-512",
|
|
1668
|
-
"content": "
|
|
1668
|
+
"content": "b9162623770ee4a9879f501417f123fe02d819cfac322ca9fde4ca86c0319a4785a6a2bd719a2b9248e531cd8eac0a79c98b5f627c69b4dfb0d5e62f69f600d5"
|
|
1669
1669
|
}
|
|
1670
1670
|
]
|
|
1671
1671
|
},
|
|
@@ -1751,11 +1751,11 @@
|
|
|
1751
1751
|
"hashes": [
|
|
1752
1752
|
{
|
|
1753
1753
|
"alg": "SHA-256",
|
|
1754
|
-
"content": "
|
|
1754
|
+
"content": "26f77d56ab70b31946f08cd83c8cd5fc43e807c77955a0e9d4ae9450d32e29c9"
|
|
1755
1755
|
},
|
|
1756
1756
|
{
|
|
1757
1757
|
"alg": "SHA3-512",
|
|
1758
|
-
"content": "
|
|
1758
|
+
"content": "b2bfaea029b51a059fb31a734fa65e73366bf075e38af76723fda119fe9202a17a286b3e20b8e7d12b16e7eed9ef68e13e7b652ddb989d3c5cab30077e7748d2"
|
|
1759
1759
|
}
|
|
1760
1760
|
]
|
|
1761
1761
|
},
|
|
@@ -2201,11 +2201,11 @@
|
|
|
2201
2201
|
"hashes": [
|
|
2202
2202
|
{
|
|
2203
2203
|
"alg": "SHA-256",
|
|
2204
|
-
"content": "
|
|
2204
|
+
"content": "576480c2ad29550a06e5a3e48b7dae04aadc1b505d76e3a5b1db9179d61263c4"
|
|
2205
2205
|
},
|
|
2206
2206
|
{
|
|
2207
2207
|
"alg": "SHA3-512",
|
|
2208
|
-
"content": "
|
|
2208
|
+
"content": "e3370698400f8b807680cebda861e73acedbf1602c9a7c2a8372c2285b2f88650a9d6e2931ebdb2cb229ad23e7c592787dea15a91adea5b4a854c6fc6842d38a"
|
|
2209
2209
|
}
|
|
2210
2210
|
]
|
|
2211
2211
|
},
|
|
@@ -2321,11 +2321,11 @@
|
|
|
2321
2321
|
"hashes": [
|
|
2322
2322
|
{
|
|
2323
2323
|
"alg": "SHA-256",
|
|
2324
|
-
"content": "
|
|
2324
|
+
"content": "4622fd121015535bb0a1b47a7bf57abe3a195b02e42a0be99dfadc9d67a72160"
|
|
2325
2325
|
},
|
|
2326
2326
|
{
|
|
2327
2327
|
"alg": "SHA3-512",
|
|
2328
|
-
"content": "
|
|
2328
|
+
"content": "85f755a9228afe24b704d39d58ee11436c8dd663df47e8c7c84da9454c5bad1cf9f166c833a9648517f9c2689730103617b41bec0739c637d91fafb041f7db63"
|
|
2329
2329
|
}
|
|
2330
2330
|
]
|
|
2331
2331
|
},
|
|
@@ -2471,11 +2471,11 @@
|
|
|
2471
2471
|
"hashes": [
|
|
2472
2472
|
{
|
|
2473
2473
|
"alg": "SHA-256",
|
|
2474
|
-
"content": "
|
|
2474
|
+
"content": "a5a43d931bcc09f0e5866e5860efd373943e5ce797ff368dc009ea4161d03cd6"
|
|
2475
2475
|
},
|
|
2476
2476
|
{
|
|
2477
2477
|
"alg": "SHA3-512",
|
|
2478
|
-
"content": "
|
|
2478
|
+
"content": "dff963f00485e37546f605542d94d5e8730be9b888d98dd9bc9d256f38b4820d3c3346b1bfdbacedefc4b47d7b07afffdd1b3d7a77ba4cf71593efdd5530b9af"
|
|
2479
2479
|
}
|
|
2480
2480
|
]
|
|
2481
2481
|
},
|
|
@@ -3101,11 +3101,11 @@
|
|
|
3101
3101
|
"hashes": [
|
|
3102
3102
|
{
|
|
3103
3103
|
"alg": "SHA-256",
|
|
3104
|
-
"content": "
|
|
3104
|
+
"content": "23d15c234afedec011d9c3e588334132373a22d09ef33cd2d943e479c88fcb43"
|
|
3105
3105
|
},
|
|
3106
3106
|
{
|
|
3107
3107
|
"alg": "SHA3-512",
|
|
3108
|
-
"content": "
|
|
3108
|
+
"content": "d4da986f67c1b537431731f28ac048bdca8bba2269896fe674aecc91d5da99d4963624e62309c60ec4c8a2422e0ed3899290a1f951db0eaf0fe46b43a90ebc74"
|
|
3109
3109
|
}
|
|
3110
3110
|
]
|
|
3111
3111
|
},
|
|
@@ -3266,11 +3266,11 @@
|
|
|
3266
3266
|
"hashes": [
|
|
3267
3267
|
{
|
|
3268
3268
|
"alg": "SHA-256",
|
|
3269
|
-
"content": "
|
|
3269
|
+
"content": "bb7cb7e49f82a7bb2a75ebcacc0b673d564384c0382ee7b271c32dd46fde8928"
|
|
3270
3270
|
},
|
|
3271
3271
|
{
|
|
3272
3272
|
"alg": "SHA3-512",
|
|
3273
|
-
"content": "
|
|
3273
|
+
"content": "49cd6309d13cfde3a266a7a499bce75849e61b562eaba579b814bd2d553f0dc192fd987eba449e86691645a22459b3579bd32dac8bd1a50697d3bb2a2045d6a0"
|
|
3274
3274
|
}
|
|
3275
3275
|
]
|
|
3276
3276
|
},
|
|
@@ -3281,11 +3281,26 @@
|
|
|
3281
3281
|
"hashes": [
|
|
3282
3282
|
{
|
|
3283
3283
|
"alg": "SHA-256",
|
|
3284
|
-
"content": "
|
|
3284
|
+
"content": "31a30c4d7ea405ad1799322c02334993f7985bf922246e621b3d3e8a402654f5"
|
|
3285
3285
|
},
|
|
3286
3286
|
{
|
|
3287
3287
|
"alg": "SHA3-512",
|
|
3288
|
-
"content": "
|
|
3288
|
+
"content": "1a33019f5533ecff0b7e97ce9d2433e83e054afd2ef3cd3902428037a4b34590820b064deeffcc4cfb92724e67f9e035fd2f2bc7f70e99128c2c7baf8d82070e"
|
|
3289
|
+
}
|
|
3290
|
+
]
|
|
3291
|
+
},
|
|
3292
|
+
{
|
|
3293
|
+
"bom-ref": "file:vendor/blamejs/codepoint-class.js",
|
|
3294
|
+
"type": "file",
|
|
3295
|
+
"name": "vendor/blamejs/codepoint-class.js",
|
|
3296
|
+
"hashes": [
|
|
3297
|
+
{
|
|
3298
|
+
"alg": "SHA-256",
|
|
3299
|
+
"content": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba"
|
|
3300
|
+
},
|
|
3301
|
+
{
|
|
3302
|
+
"alg": "SHA3-512",
|
|
3303
|
+
"content": "8e243451500312f0836651525e31150f649b39ec34caa662bfff86f65975af91e479fd7b74a971ddb4a1fc30a379dc958b0407f7c5193c4e28a215a56a8e2bd4"
|
|
3289
3304
|
}
|
|
3290
3305
|
]
|
|
3291
3306
|
},
|
|
@@ -3319,6 +3334,46 @@
|
|
|
3319
3334
|
}
|
|
3320
3335
|
]
|
|
3321
3336
|
},
|
|
3337
|
+
{
|
|
3338
|
+
"bom-ref": "vendor:blamejs:codepoint-class.js",
|
|
3339
|
+
"type": "library",
|
|
3340
|
+
"name": "blamejs/codepoint-class.js",
|
|
3341
|
+
"version": "1442f17758a4",
|
|
3342
|
+
"description": "Vendored from blamejs/lib/codepoint-class.js (flattened + stripped). See vendor/blamejs/README.md.",
|
|
3343
|
+
"licenses": [
|
|
3344
|
+
{
|
|
3345
|
+
"license": {
|
|
3346
|
+
"id": "Apache-2.0"
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
],
|
|
3350
|
+
"hashes": [
|
|
3351
|
+
{
|
|
3352
|
+
"alg": "SHA-256",
|
|
3353
|
+
"content": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba"
|
|
3354
|
+
}
|
|
3355
|
+
],
|
|
3356
|
+
"externalReferences": [
|
|
3357
|
+
{
|
|
3358
|
+
"type": "vcs",
|
|
3359
|
+
"url": "https://github.com/blamejs/blamejs"
|
|
3360
|
+
},
|
|
3361
|
+
{
|
|
3362
|
+
"type": "distribution",
|
|
3363
|
+
"url": "https://github.com/blamejs/blamejs/blob/1442f17758a4bd511c63877561c0ffa759f66a87/lib/codepoint-class.js"
|
|
3364
|
+
}
|
|
3365
|
+
],
|
|
3366
|
+
"properties": [
|
|
3367
|
+
{
|
|
3368
|
+
"name": "exceptd:vendor:upstream_sha256_at_pin",
|
|
3369
|
+
"value": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba"
|
|
3370
|
+
},
|
|
3371
|
+
{
|
|
3372
|
+
"name": "exceptd:vendor:strip_summary",
|
|
3373
|
+
"value": ""
|
|
3374
|
+
}
|
|
3375
|
+
]
|
|
3376
|
+
},
|
|
3322
3377
|
{
|
|
3323
3378
|
"bom-ref": "vendor:blamejs:retry.js",
|
|
3324
3379
|
"type": "library",
|
|
@@ -41,6 +41,7 @@ const ROOT = path.resolve(__dirname, "..");
|
|
|
41
41
|
const VALID_ALLOW_CLASSES = Object.freeze({
|
|
42
42
|
"process-exit-after-stdout-write": true,
|
|
43
43
|
"dynamic-regex": true,
|
|
44
|
+
"bidi-codepoint-literal": true,
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
const EXCLUDE_DIRS = new Set([
|
|
@@ -205,6 +206,39 @@ function detectDynamicRegex(files) {
|
|
|
205
206
|
return filterMarkers(hits, "dynamic-regex");
|
|
206
207
|
}
|
|
207
208
|
|
|
209
|
+
// Raw bidi-override / zero-width / invisible / null codepoints embedded as
|
|
210
|
+
// literals in source — the Trojan-Source class (CVE-2021-42574). A literal
|
|
211
|
+
// such codepoint is invisible in review and can reorder or hide code. Source
|
|
212
|
+
// should emit them programmatically (via vendor/blamejs/codepoint-class) or
|
|
213
|
+
// escape them (\uXXXX), never type them literally. The range table holds only
|
|
214
|
+
// numeric codepoints + the regex is built from escapes, so this detector's own
|
|
215
|
+
// source is clean (and the file self-skips below regardless).
|
|
216
|
+
const _BIDI_LITERAL_RANGES = [
|
|
217
|
+
[0x202A, 0x202E], [0x2066, 0x2069], 0x200E, 0x200F, 0x061C, // bidi overrides + isolates
|
|
218
|
+
0x200B, 0x200C, 0x200D, 0x00AD, 0x2060, 0xFEFF, // zero-width / invisible
|
|
219
|
+
0x0000, // null
|
|
220
|
+
];
|
|
221
|
+
function _bidiLiteralRe() {
|
|
222
|
+
const body = _BIDI_LITERAL_RANGES.map((r) =>
|
|
223
|
+
Array.isArray(r)
|
|
224
|
+
? "\\u" + r[0].toString(16).padStart(4, "0") + "-\\u" + r[1].toString(16).padStart(4, "0")
|
|
225
|
+
: "\\u" + r.toString(16).padStart(4, "0")
|
|
226
|
+
).join("");
|
|
227
|
+
return new RegExp("[" + body + "]"); // allow:dynamic-regex — codepoints from a static literal range table, not operator input
|
|
228
|
+
}
|
|
229
|
+
function detectBidiCodepointLiteral(files) {
|
|
230
|
+
const re = _bidiLiteralRe();
|
|
231
|
+
const hits = [];
|
|
232
|
+
for (const rel of (files || filesUnder(["bin/exceptd.js", "lib", "orchestrator", "scripts"]))) {
|
|
233
|
+
if (rel === "scripts/check-codebase-patterns.js") continue; // holds the range table itself
|
|
234
|
+
const lines = readLines(rel);
|
|
235
|
+
for (let i = 0; i < lines.length; i++) {
|
|
236
|
+
if (re.test(lines[i])) hits.push({ file: rel, line: i + 1, content: lines[i].trim() });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return filterMarkers(hits, "bidi-codepoint-literal");
|
|
240
|
+
}
|
|
241
|
+
|
|
208
242
|
function detectOrphanAllowClass(files) {
|
|
209
243
|
const hits = [];
|
|
210
244
|
for (const rel of (files || filesUnder(["bin/exceptd.js", "lib", "orchestrator", "scripts"]))) {
|
|
@@ -251,6 +285,12 @@ const CLASSES = [
|
|
|
251
285
|
warnOnly: true, // flip to false next release once the known sites carry markers
|
|
252
286
|
hint: "RegExp from operator input is a ReDoS sink — anchor + length-cap, or `// allow:dynamic-regex — <reason>` when the pattern is a trusted bundled schema",
|
|
253
287
|
},
|
|
288
|
+
{
|
|
289
|
+
id: "bidi-codepoint-literal",
|
|
290
|
+
run: detectBidiCodepointLiteral,
|
|
291
|
+
warnOnly: false,
|
|
292
|
+
hint: "raw bidi/zero-width/null codepoint in source — emit it via vendor/blamejs/codepoint-class tables or a \\uXXXX escape, or `// allow:bidi-codepoint-literal — <reason>` if the literal is load-bearing test/illustrative data",
|
|
293
|
+
},
|
|
254
294
|
{
|
|
255
295
|
id: "orphan-allow-class",
|
|
256
296
|
run: detectOrphanAllowClass,
|
|
@@ -289,6 +329,7 @@ module.exports = {
|
|
|
289
329
|
CLASSES,
|
|
290
330
|
detectProcessExitAfterStdout,
|
|
291
331
|
detectDynamicRegex,
|
|
332
|
+
detectBidiCodepointLiteral,
|
|
292
333
|
detectOrphanAllowClass,
|
|
293
334
|
filesUnder,
|
|
294
335
|
};
|
package/scripts/predeploy.js
CHANGED
|
@@ -244,7 +244,7 @@ const GATES = [
|
|
|
244
244
|
// dynamic-RegExp construction is surfaced warn-only this release. The
|
|
245
245
|
// exception mechanism + the "owned elsewhere" boundary are documented in
|
|
246
246
|
// the script header.
|
|
247
|
-
name: "Codebase-pattern gates (
|
|
247
|
+
name: "Codebase-pattern gates (stdout-flush, dynamic RegExp, bidi codepoints, orphan markers)",
|
|
248
248
|
command: process.execPath,
|
|
249
249
|
args: [path.join(ROOT, "scripts", "check-codebase-patterns.js")],
|
|
250
250
|
ciJobName: "Data integrity (catalog + manifest snapshot)",
|
package/scripts/release.js
CHANGED
|
@@ -375,6 +375,22 @@ function cmdWatch() {
|
|
|
375
375
|
// run doesn't throw before we get to inspect + rerun it.
|
|
376
376
|
_run("gh", ["pr", "checks", prNum, "--watch"], { allowFail: true });
|
|
377
377
|
|
|
378
|
+
// Gate on check CONCLUSIONS, not only review threads. A red required check
|
|
379
|
+
// leaves the PR BLOCKED at merge, so surfacing failures here (the whole
|
|
380
|
+
// point of the watch phase) beats advancing to "next: merge" and letting
|
|
381
|
+
// cmdMerge reject it. Bucket is gh's normalized verdict: pass / fail /
|
|
382
|
+
// pending / skipping / cancel.
|
|
383
|
+
var checksRaw = _capture("gh", ["pr", "checks", prNum, "--json", "name,bucket,link"]).stdout;
|
|
384
|
+
var checks = [];
|
|
385
|
+
try { checks = JSON.parse(checksRaw || "[]"); } catch (_e) { checks = []; }
|
|
386
|
+
var failed = checks.filter(function (c) { return c.bucket === "fail" || c.bucket === "cancel"; });
|
|
387
|
+
if (failed.length > 0) {
|
|
388
|
+
console.log("\nfailed checks (" + failed.length + "):");
|
|
389
|
+
failed.forEach(function (c) { console.log(" ✗ " + c.name + " " + (c.link || "")); });
|
|
390
|
+
console.log("\nFix in code, push, then re-run: node scripts/release.js watch");
|
|
391
|
+
process.exit(3);
|
|
392
|
+
}
|
|
393
|
+
|
|
378
394
|
var unresolved = _unresolvedThreads(prNum);
|
|
379
395
|
if (unresolved.length > 0) {
|
|
380
396
|
console.log("\nunresolved review threads (" + unresolved.length + "):");
|
|
@@ -85,6 +85,8 @@ The defining incidents driving this expansion:
|
|
|
85
85
|
- **Typosquat campaigns target the MCP, Hugging Face, npm `@modelcontextprotocol/*`, and PyPI ML namespaces.** The MITRE ATLAS technique AML.T0010 (ML Supply Chain Compromise) is the umbrella class; AML.T0018 (compromised model weight) is the specific artifact.
|
|
86
86
|
- **The XZ Utils backdoor (2024, CVE-2024-3094)** remains the canonical example of a maintainer-position long-game supply-chain compromise that no SBOM-only program detects. The defense is in-toto attestation chain plus reproducible builds plus maintainer-key transparency — none of which are mandated by current compliance frameworks.
|
|
87
87
|
|
|
88
|
+
**Capability surface is a CVE-independent screening lens.** Beyond matching dependencies against catalogued CVEs, classify every package by the capabilities it actually exercises — network egress, filesystem write, shell/process spawn, environment and credential access, dynamic `eval`, install-lifecycle scripts, telemetry, and native-binary builds. A package with zero catalogued CVEs can still carry the supply-chain delivery primitive: an install-script that spawns a shell, opens the network, and reads environment variables is the credential-harvesting shape shared by the node-ipc protestware wiper (CVE-2022-23812), the TrapDoor cross-ecosystem stealer, the MOIKA dependency-confusion campaign, and the XZ backdoor — independent of whether any of them is yet in a vulnerability feed. Two deltas matter most: a capability surface disproportionate to a package's stated function (a date-formatting utility that opens the network and reads env), and a capability *gained across a version bump* the dependent never opted into when it first selected the package — the in-the-wild signature of a maintainer-account takeover or protestware injection before any CVE is assigned. Build-tooling and native-addon packages (node-gyp, esbuild, sharp, prebuild-install) legitimately carry install-script and native-binary capability, so treat the lens as a high-recall screen that routes to adjudication against publisher provenance and changelog evidence — not an auto-verdict.
|
|
89
|
+
|
|
88
90
|
Mid-2026 baseline expectations have shifted to: SLSA Build L3 minimum on every release pipeline; in-toto attestations for every step in the build graph; Sigstore keyless signing (cosign + Fulcio + Rekor) for container images, packages, and model weights; CycloneDX 1.6 or SPDX 3.0 SBOM at build time and re-verification at deploy time; CSAF 2.0 VEX statements published by vendors and consumed by operators to filter false-positive vulnerability noise. Adoption is uneven — security-mature orgs and open-source foundations (Kubernetes, Sigstore, Linux Foundation projects) are at or near this baseline; most enterprise pipelines are between SLSA L1 and L2 with no attestation chain and no VEX consumption.
|
|
89
91
|
|
|
90
92
|
This project itself uses Ed25519 (RFC 8032) signing for skill integrity (`lib/sign.js`, `lib/verify.js`, public key at `keys/public.pem`). That is the smallest-scale living example of the broader pattern this skill defines: artifacts are signed by an identified key, signatures are verified before load, tampered artifacts are rejected, and the signing key is operationally separated from the artifact registry. The same pattern scales to every layer of the build pipeline — exceptd is just the scoped-to-one-repo version.
|
package/vendor/blamejs/README.md
CHANGED
|
@@ -9,6 +9,7 @@ upstream commit [`1442f17`](https://github.com/blamejs/blamejs/commit/1442f17758
|
|
|
9
9
|
|---|---|---|
|
|
10
10
|
| `retry.js` | `lib/retry.js` | Battle-tested exponential backoff + crypto jitter + AbortSignal + circuit-breaker. Used by `lib/job-queue.js` and `lib/refresh-external.js` for HTTP retry semantics on KEV/EPSS/NVD/IETF/GitHub fetches. |
|
|
11
11
|
| `worker-pool.js` | `lib/worker-pool.js` | Generic worker_threads pool with bounded queue, per-task timeout, worker recycle. Used by `scripts/build-indexes.js --parallel` and any future CPU-bound fan-out work. |
|
|
12
|
+
| `codepoint-class.js` | `lib/codepoint-class.js` | Trojan-Source (CVE-2021-42574) codepoint threat tables — bidi-override / C0-control / zero-width / null ranges + compiled regexes + `applyCharStripPolicies`. Used by the `--operator` reject path (`bin/exceptd.js`) and `sanitizeOperatorText` (`lib/playbook-runner.js`) to classify which family an offending codepoint belongs to; `\p{C}` remains the category backstop. |
|
|
12
13
|
| `LICENSE` | `LICENSE` | Apache-2.0 license text (identical to exceptd's). |
|
|
13
14
|
| `_PROVENANCE.json` | — | sha256 of each vendored file + upstream file at pin, plus the strip rules applied. `lib/validate-vendor.js` re-hashes on every predeploy run. |
|
|
14
15
|
|
|
@@ -52,6 +52,22 @@
|
|
|
52
52
|
"exceptd_deltas": [
|
|
53
53
|
"scriptPath validator rejects Windows UNC + extended-path prefixes (\\\\?\\, \\\\.\\, \\\\<server>\\) — defense-in-depth against worker-spawn from network shares on win32 platforms"
|
|
54
54
|
]
|
|
55
|
+
},
|
|
56
|
+
"codepoint-class.js": {
|
|
57
|
+
"vendored_path": "vendor/blamejs/codepoint-class.js",
|
|
58
|
+
"vendored_sha256": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba",
|
|
59
|
+
"upstream_path": "lib/codepoint-class.js",
|
|
60
|
+
"upstream_sha256_at_pin": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba",
|
|
61
|
+
"stripped": [],
|
|
62
|
+
"surface_preserved": [
|
|
63
|
+
"BIDI_RE / C0_CTRL_RE / ZERO_WIDTH_RE / NULL_BYTE (classification regexes)",
|
|
64
|
+
"BIDI_RE_G / C0_CTRL_RE_G / ZW_RE_G / NULL_RE_G (global strip regexes)",
|
|
65
|
+
"applyCharStripPolicies(text, opts)",
|
|
66
|
+
"hex4 / charClass / fromCp / range tables"
|
|
67
|
+
],
|
|
68
|
+
"exceptd_deltas": [
|
|
69
|
+
"Used for codepoint-family CLASSIFICATION + family-strip only. The BIDI|C0|ZERO_WIDTH|NULL union is a strict subset of Unicode General Category C, so \\p{C} remains the reject/strip backstop at both consumer sites (bin/exceptd.js --operator validation, lib/playbook-runner.js sanitizeOperatorText) — it catches the divergent remainder (U+007F, U+0080-009F, U+FFF9-FFFB, private-use, unassigned) the named-family regexes miss."
|
|
70
|
+
]
|
|
55
71
|
}
|
|
56
72
|
}
|
|
57
73
|
}
|