@clear-capabilities/agentic-security-scanner 0.84.1 → 0.118.2
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 +404 -0
- package/dist/178.index.js +1 -1
- package/dist/384.index.js +1 -1
- package/dist/637.index.js +1 -1
- package/dist/838.index.js +1 -1
- package/dist/agentic-security.mjs +84 -84
- package/dist/agentic-security.mjs.sha256 +1 -1
- package/package.json +12 -6
- package/src/.agentic-security/dpia.md +26 -0
- package/src/.agentic-security/pqc-migration-plan.json +80 -0
- package/src/.agentic-security/pqc-migration-plan.md +32 -0
- package/src/.agentic-security/sbom-history/0775d96ba4cf814520d02760cfb3010760c7684f.json +6 -0
- package/src/.agentic-security/sbom-history/29300441d3460832137a8e51a92b74068cad2f15.json +6 -0
- package/src/.agentic-security/sbom-history/3852ad2aa0e50951bed0c930c29d1861aa13d048.json +6 -0
- package/src/.agentic-security/sbom-history/3d96e2daec97e3226c9679bac6e64a89ca10bfe9.json +6 -0
- package/src/.agentic-security/sbom-history/5f0b136622fce09b469a1a6137c04d5b18652ea4.json +6 -0
- package/src/.agentic-security/sbom-history/64e30595d447b62344d0d9200760269df2095332.json +6 -0
- package/src/.agentic-security/sbom-history/71f3241902c9e7437764e3caa046ba8a3bcdd32a.json +6 -0
- package/src/.agentic-security/sbom-history/99c372cdc33ecc9dde92960b4ffadf7775860e61.json +6 -0
- package/src/.agentic-security/sbom-history/9c93b15e8cf3ff2ddb8cdae92371b82e178b463c.json +6 -0
- package/src/.agentic-security/sbom-history/a3544abf1863d71776b61302ca74d9ead2b26a9f.json +6 -0
- package/src/.agentic-security/sbom-history/dca15abdec43c508aa342db86dc5db8d7f01fbbe.json +6 -0
- package/src/.agentic-security/threat-model.json +3702 -0
- package/src/.agentic-security/threat-model.md +118 -0
- package/src/dataflow/.agentic-security/dpia.md +26 -0
- package/src/dataflow/.agentic-security/sbom-history/15d7c4d20f9d968ebec29445c9e9b3fc6f74e6a1.json +6 -0
- package/src/dataflow/.agentic-security/sbom-history/3852ad2aa0e50951bed0c930c29d1861aa13d048.json +6 -0
- package/src/dataflow/.agentic-security/sbom-history/73166872888d9ddcbe98645af818ecc7d8917b07.json +6 -0
- package/src/dataflow/.agentic-security/sbom-history/8869fe64035bec0152d92ece961e9369d8637076.json +6 -0
- package/src/dataflow/.agentic-security/sbom-history/9c93b15e8cf3ff2ddb8cdae92371b82e178b463c.json +6 -0
- package/src/dataflow/.agentic-security/sbom-history/b7ac2dada4a9216ccfe8969fc57f988c83f46975.json +6 -0
- package/src/dataflow/.agentic-security/threat-model.json +161 -0
- package/src/dataflow/.agentic-security/threat-model.md +43 -0
- package/src/dataflow/CLAUDE.md +17 -5
- package/src/dataflow/catalog.js +9 -0
- package/src/dataflow/engine.js +30 -4
- package/src/dataflow/index.js +8 -0
- package/src/dataflow/proof-gate.js +95 -0
- package/src/dataflow/summaries.js +44 -5
- package/src/engine.js +199 -5
- package/src/ir/.agentic-security/dpia.md +26 -0
- package/src/ir/.agentic-security/exploit-bundles.json +77 -0
- package/src/ir/.agentic-security/sbom-history/73166872888d9ddcbe98645af818ecc7d8917b07.json +6 -0
- package/src/ir/.agentic-security/sbom-history/b5f468a158f6a145aedd8680841c106b9809f16b.json +6 -0
- package/src/ir/.agentic-security/threat-model.json +143 -0
- package/src/ir/.agentic-security/threat-model.md +39 -0
- package/src/ir/CLAUDE.md +1 -0
- package/src/ir/callgraph.js +12 -1
- package/src/ir/tree-sitter-loader.js +108 -0
- package/src/posture/.agentic-security/dpia.md +26 -0
- package/src/posture/.agentic-security/pqc-migration-plan.json +65 -0
- package/src/posture/.agentic-security/pqc-migration-plan.md +30 -0
- package/src/posture/.agentic-security/sbom-history/0724c133d2943c87555695b5b2adcfcfc3373a2d.json +6 -0
- package/src/posture/.agentic-security/sbom-history/7d45b5e03804aac084b4a2b4dc8c6f10107d2005.json +6 -0
- package/src/posture/.agentic-security/sbom-history/99c372cdc33ecc9dde92960b4ffadf7775860e61.json +6 -0
- package/src/posture/.agentic-security/sbom-history/b7ac2dada4a9216ccfe8969fc57f988c83f46975.json +6 -0
- package/src/posture/.agentic-security/threat-model.json +2038 -0
- package/src/posture/.agentic-security/threat-model.md +73 -0
- package/src/posture/auditor-walkthrough.js +1 -1
- package/src/posture/corpus-status.js +74 -0
- package/src/posture/coverage-report.js +113 -0
- package/src/posture/holdout-eval.js +57 -0
- package/src/posture/pr-augment.js +1 -1
- package/src/posture/router.js +37 -7
- package/src/report/.agentic-security/dpia.md +26 -0
- package/src/report/.agentic-security/sbom-history/7d45b5e03804aac084b4a2b4dc8c6f10107d2005.json +6 -0
- package/src/report/.agentic-security/sbom-history/f94be839aa6a1011f53da016416a561698b8f338.json +6 -0
- package/src/report/.agentic-security/threat-model.json +7 -0
- package/src/report/.agentic-security/threat-model.md +22 -0
- package/src/report/index.js +18 -1
- package/src/sast/.agentic-security/dpia.md +26 -0
- package/src/sast/.agentic-security/pqc-migration-plan.json +65 -0
- package/src/sast/.agentic-security/pqc-migration-plan.md +30 -0
- package/src/sast/.agentic-security/sbom-history/043a7b401c68f5a298c83d4c42e94f118ff2a89a.json +6 -0
- package/src/sast/.agentic-security/sbom-history/0775d96ba4cf814520d02760cfb3010760c7684f.json +6 -0
- package/src/sast/.agentic-security/sbom-history/20d77ad7363a82777d506dedbbb1ecfed52f094a.json +6 -0
- package/src/sast/.agentic-security/sbom-history/29300441d3460832137a8e51a92b74068cad2f15.json +6 -0
- package/src/sast/.agentic-security/sbom-history/3852ad2aa0e50951bed0c930c29d1861aa13d048.json +6 -0
- package/src/sast/.agentic-security/sbom-history/3c6b3205f04e26f7654943d465281d00e0fa395e.json +6 -0
- package/src/sast/.agentic-security/sbom-history/3d96e2daec97e3226c9679bac6e64a89ca10bfe9.json +6 -0
- package/src/sast/.agentic-security/sbom-history/5282502e090013219eb006f7e02d8c983bc29c8e.json +6 -0
- package/src/sast/.agentic-security/sbom-history/5f0b136622fce09b469a1a6137c04d5b18652ea4.json +6 -0
- package/src/sast/.agentic-security/sbom-history/64e30595d447b62344d0d9200760269df2095332.json +6 -0
- package/src/sast/.agentic-security/sbom-history/71f3241902c9e7437764e3caa046ba8a3bcdd32a.json +6 -0
- package/src/sast/.agentic-security/sbom-history/73514b485d4770f3c5ee57d87338bccd1c61d8b7.json +6 -0
- package/src/sast/.agentic-security/sbom-history/96fa584fc3134512237d58aac63d6f3778b0cbcb.json +6 -0
- package/src/sast/.agentic-security/sbom-history/99c372cdc33ecc9dde92960b4ffadf7775860e61.json +6 -0
- package/src/sast/.agentic-security/sbom-history/a3544abf1863d71776b61302ca74d9ead2b26a9f.json +6 -0
- package/src/sast/.agentic-security/sbom-history/a4a34ab8b3d758de2adc8c3dc3e42d4cb0db00a3.json +6 -0
- package/src/sast/.agentic-security/sbom-history/ac236ec3602cfc8fb133f389ec3687e409084673.json +6 -0
- package/src/sast/.agentic-security/sbom-history/b57b3e1292f1f9f0de6c5a34a436e330c78008a3.json +6 -0
- package/src/sast/.agentic-security/sbom-history/dca15abdec43c508aa342db86dc5db8d7f01fbbe.json +6 -0
- package/src/sast/.agentic-security/sbom-history/dcbfd4935922dd165093c08a1003c338eed937c5.json +6 -0
- package/src/sast/.agentic-security/sbom-history/fa017f725615b0293814344c8ef7dfeb06775ca0.json +6 -0
- package/src/sast/.agentic-security/threat-model.json +816 -0
- package/src/sast/.agentic-security/threat-model.md +91 -0
- package/src/sast/CLAUDE.md +9 -3
- package/src/sast/code-injection-multilang.js +117 -0
- package/src/sast/crypto-protocol.js +43 -1
- package/src/sast/csharp-structural.js +65 -0
- package/src/sast/csharp.js +3 -0
- package/src/sast/csrf.js +24 -3
- package/src/sast/csv-injection.js +84 -0
- package/src/sast/frontend-hygiene.js +106 -0
- package/src/sast/go-structural.js +60 -0
- package/src/sast/java-structural.js +81 -0
- package/src/sast/js-framework-structural.js +115 -0
- package/src/sast/kotlin.js +72 -0
- package/src/sast/ldap-injection.js +73 -17
- package/src/sast/open-redirect.js +47 -5
- package/src/sast/php.js +35 -0
- package/src/sast/python-structural.js +83 -0
- package/src/sast/redos-nfa.js +75 -0
- package/src/sast/response-splitting.js +48 -19
- package/src/sast/ruby.js +38 -0
- package/src/sast/secret-concat.js +60 -0
- package/src/sast/ssrf-cloud-metadata.js +13 -0
- package/src/sast/stored-taint.js +88 -0
- package/src/sast/tree-sitter-sinks.js +62 -0
- package/src/sast/weak-password-hash.js +28 -0
- package/src/sast/weak-randomness.js +46 -5
- package/src/sast/wrong-context-sanitizer.js +94 -0
- package/src/sast/xpath-injection.js +30 -6
- package/src/sast/xss-reflected-multilang.js +116 -0
- package/src/sast/xxe.js +67 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
{
|
|
2
|
+
"entities": [],
|
|
3
|
+
"boundaries": [],
|
|
4
|
+
"assets": [],
|
|
5
|
+
"threats": [
|
|
6
|
+
{
|
|
7
|
+
"stride": "T",
|
|
8
|
+
"strideLabel": "Tampering",
|
|
9
|
+
"cwe": "CWE-915",
|
|
10
|
+
"family": "mass-assignment",
|
|
11
|
+
"severity": "high",
|
|
12
|
+
"file": "parser-cs.js",
|
|
13
|
+
"vuln": "Mass Assignment (req.body Direct to Model)",
|
|
14
|
+
"finding_id": "struct:parser-cs.js:208:Mass_Assignment_(req.body_Direct_to_Model)",
|
|
15
|
+
"affectsAsset": null,
|
|
16
|
+
"atEntity": null
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"stride": "T",
|
|
20
|
+
"strideLabel": "Tampering",
|
|
21
|
+
"cwe": "CWE-915",
|
|
22
|
+
"family": "mass-assignment",
|
|
23
|
+
"severity": "high",
|
|
24
|
+
"file": "parser-go.js",
|
|
25
|
+
"vuln": "Mass Assignment (req.body Direct to Model)",
|
|
26
|
+
"finding_id": "struct:parser-go.js:253:Mass_Assignment_(req.body_Direct_to_Model)",
|
|
27
|
+
"affectsAsset": null,
|
|
28
|
+
"atEntity": null
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"stride": "T",
|
|
32
|
+
"strideLabel": "Tampering",
|
|
33
|
+
"cwe": "CWE-915",
|
|
34
|
+
"family": "mass-assignment",
|
|
35
|
+
"severity": "high",
|
|
36
|
+
"file": "parser-kt.js",
|
|
37
|
+
"vuln": "Mass Assignment (req.body Direct to Model)",
|
|
38
|
+
"finding_id": "struct:parser-kt.js:207:Mass_Assignment_(req.body_Direct_to_Model)",
|
|
39
|
+
"affectsAsset": null,
|
|
40
|
+
"atEntity": null
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"stride": "T",
|
|
44
|
+
"strideLabel": "Tampering",
|
|
45
|
+
"cwe": "CWE-915",
|
|
46
|
+
"family": "mass-assignment",
|
|
47
|
+
"severity": "high",
|
|
48
|
+
"file": "parser-php.js",
|
|
49
|
+
"vuln": "Mass Assignment (req.body Direct to Model)",
|
|
50
|
+
"finding_id": "struct:parser-php.js:209:Mass_Assignment_(req.body_Direct_to_Model)",
|
|
51
|
+
"affectsAsset": null,
|
|
52
|
+
"atEntity": null
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"stride": "T",
|
|
56
|
+
"strideLabel": "Tampering",
|
|
57
|
+
"cwe": "CWE-915",
|
|
58
|
+
"family": "mass-assignment",
|
|
59
|
+
"severity": "high",
|
|
60
|
+
"file": "parser-rb.js",
|
|
61
|
+
"vuln": "Mass Assignment (req.body Direct to Model)",
|
|
62
|
+
"finding_id": "struct:parser-rb.js:201:Mass_Assignment_(req.body_Direct_to_Model)",
|
|
63
|
+
"affectsAsset": null,
|
|
64
|
+
"atEntity": null
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"stride": "T",
|
|
68
|
+
"strideLabel": "Tampering",
|
|
69
|
+
"cwe": "CWE-400",
|
|
70
|
+
"family": "dos-sync-io",
|
|
71
|
+
"severity": "medium",
|
|
72
|
+
"file": "cpp-preprocessor.js",
|
|
73
|
+
"vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
|
|
74
|
+
"finding_id": "struct:cpp-preprocessor.js:94:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
|
|
75
|
+
"affectsAsset": null,
|
|
76
|
+
"atEntity": null
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"stride": "T",
|
|
80
|
+
"strideLabel": "Tampering",
|
|
81
|
+
"cwe": "CWE-400",
|
|
82
|
+
"family": "dos-sync-io",
|
|
83
|
+
"severity": "medium",
|
|
84
|
+
"file": "type-stubs.js",
|
|
85
|
+
"vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
|
|
86
|
+
"finding_id": "struct:type-stubs.js:48:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
|
|
87
|
+
"affectsAsset": null,
|
|
88
|
+
"atEntity": null
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"stride": "T",
|
|
92
|
+
"strideLabel": "Tampering",
|
|
93
|
+
"cwe": "CWE-400",
|
|
94
|
+
"family": "dos-sync-io",
|
|
95
|
+
"severity": "medium",
|
|
96
|
+
"file": "parser-py-cst.js",
|
|
97
|
+
"vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
|
|
98
|
+
"finding_id": "struct:parser-py-cst.js:91:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
|
|
99
|
+
"affectsAsset": null,
|
|
100
|
+
"atEntity": null
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"stride": "I",
|
|
104
|
+
"strideLabel": "Information Disclosure",
|
|
105
|
+
"cwe": "CWE-327",
|
|
106
|
+
"family": "crypto-weak-hash",
|
|
107
|
+
"severity": "medium",
|
|
108
|
+
"file": "parser-py.helper.py",
|
|
109
|
+
"line": 68,
|
|
110
|
+
"vuln": "Weak hash algorithm (MD5 / SHA-1 / MD2 / MD4) used",
|
|
111
|
+
"finding_id": "crypto-weak-hash:parser-py.helper.py:68",
|
|
112
|
+
"affectsAsset": null,
|
|
113
|
+
"atEntity": null
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"stride": "T",
|
|
117
|
+
"strideLabel": "Tampering",
|
|
118
|
+
"cwe": "CWE-367",
|
|
119
|
+
"family": "toctou-file-existence-permission-check-b",
|
|
120
|
+
"severity": "medium",
|
|
121
|
+
"file": "type-stubs.js",
|
|
122
|
+
"line": 48,
|
|
123
|
+
"vuln": "TOCTOU: file existence/permission check before open",
|
|
124
|
+
"finding_id": "toctou-fs:type-stubs.js:48",
|
|
125
|
+
"affectsAsset": null,
|
|
126
|
+
"atEntity": null
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"stride": "T",
|
|
130
|
+
"strideLabel": "Tampering",
|
|
131
|
+
"cwe": "CWE-176",
|
|
132
|
+
"family": "path-normalization",
|
|
133
|
+
"severity": "medium",
|
|
134
|
+
"file": "universal-ir.js",
|
|
135
|
+
"line": 93,
|
|
136
|
+
"vuln": "Path Normalization Gap — extension extraction without null-byte/traversal sanitization",
|
|
137
|
+
"finding_id": "path-norm:universal-ir.js:93",
|
|
138
|
+
"affectsAsset": null,
|
|
139
|
+
"atEntity": null
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"attackTrees": []
|
|
143
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Threat Model (auto-generated)
|
|
2
|
+
|
|
3
|
+
Generated by agentic-security on 2026-05-31.
|
|
4
|
+
|
|
5
|
+
This threat model is derived from static analysis of the current codebase and is regenerated on every scan. It is intended as a working artifact, not a finished compliance document.
|
|
6
|
+
|
|
7
|
+
## Entities + boundaries
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
flowchart TB
|
|
11
|
+
subgraph External
|
|
12
|
+
end
|
|
13
|
+
subgraph Application
|
|
14
|
+
end
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Assets
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## STRIDE threats
|
|
21
|
+
|
|
22
|
+
### Tampering (10)
|
|
23
|
+
|
|
24
|
+
- [high] **mass-assignment** (CWE-915) at `parser-cs.js:undefined` — Mass Assignment (req.body Direct to Model)
|
|
25
|
+
- [high] **mass-assignment** (CWE-915) at `parser-go.js:undefined` — Mass Assignment (req.body Direct to Model)
|
|
26
|
+
- [high] **mass-assignment** (CWE-915) at `parser-kt.js:undefined` — Mass Assignment (req.body Direct to Model)
|
|
27
|
+
- [high] **mass-assignment** (CWE-915) at `parser-php.js:undefined` — Mass Assignment (req.body Direct to Model)
|
|
28
|
+
- [high] **mass-assignment** (CWE-915) at `parser-rb.js:undefined` — Mass Assignment (req.body Direct to Model)
|
|
29
|
+
- [medium] **dos-sync-io** (CWE-400) at `cpp-preprocessor.js:undefined` — Synchronous Blocking I/O (DoS Risk in Server Context)
|
|
30
|
+
- [medium] **dos-sync-io** (CWE-400) at `type-stubs.js:undefined` — Synchronous Blocking I/O (DoS Risk in Server Context)
|
|
31
|
+
- [medium] **dos-sync-io** (CWE-400) at `parser-py-cst.js:undefined` — Synchronous Blocking I/O (DoS Risk in Server Context)
|
|
32
|
+
- [medium] **toctou-file-existence-permission-check-b** (CWE-367) at `type-stubs.js:48` — TOCTOU: file existence/permission check before open
|
|
33
|
+
- [medium] **path-normalization** (CWE-176) at `universal-ir.js:93` — Path Normalization Gap — extension extraction without null-byte/traversal sanitization
|
|
34
|
+
|
|
35
|
+
### Information Disclosure (1)
|
|
36
|
+
|
|
37
|
+
- [medium] **crypto-weak-hash** (CWE-327) at `parser-py.helper.py:68` — Weak hash algorithm (MD5 / SHA-1 / MD2 / MD4) used
|
|
38
|
+
|
|
39
|
+
## Attack trees
|
package/src/ir/CLAUDE.md
CHANGED
|
@@ -11,6 +11,7 @@ consumed by `scanner/src/dataflow/` for taint analysis.
|
|
|
11
11
|
| Python | `parser-py-cst.js` | Python 3.8+ stdlib `ast` via subprocess (default when available) |
|
|
12
12
|
| Python | `parser-py.js` | Hand-rolled regex parser (fallback when python3 missing) |
|
|
13
13
|
| Java | `parser-java.js` | `java-parser` npm package (async) |
|
|
14
|
+
| Long-tail (rust/solidity/cpp/c/go/swift/dart) | `tree-sitter-loader.js` | **Optional** `web-tree-sitter` + `tree-sitter-wasms` (ABI-pinned 0.20.8 ↔ 0.1.13), lazy + degrades when absent. Powers `sast/tree-sitter-sinks.js` (opt-in via `AGENTIC_SECURITY_TREE_SITTER=1`). Marked `--external` in the build so the committed bundle never embeds WASM. |
|
|
14
15
|
|
|
15
16
|
## Python parser — dual-path with auto fallback
|
|
16
17
|
|
package/src/ir/callgraph.js
CHANGED
|
@@ -67,8 +67,19 @@ export function buildCallGraph(perFileIR, fileContents) {
|
|
|
67
67
|
// the call graph for the callee's qid at the assign-from-call site.
|
|
68
68
|
// Same precedence as the edge resolution above (same-file ident wins,
|
|
69
69
|
// ClassName.method falls back).
|
|
70
|
-
function resolve(name) {
|
|
70
|
+
function resolve(name, callerFile) {
|
|
71
71
|
if (!name || typeof name !== 'string') return null;
|
|
72
|
+
// Roadmap #3: same-file preference. A bare name (`handler`, `save`,
|
|
73
|
+
// `query`) defined in several files would otherwise resolve to whichever
|
|
74
|
+
// file Map is iterated first, mis-targeting interprocedural taint to a
|
|
75
|
+
// same-named function in an unrelated file. When the caller's own file
|
|
76
|
+
// defines the name, that is overwhelmingly the intended callee — prefer
|
|
77
|
+
// it. Backward-compatible: with no callerFile (or no local match) the
|
|
78
|
+
// original resolution order is unchanged, so no edge is ever dropped.
|
|
79
|
+
if (callerFile) {
|
|
80
|
+
const local = byNameInFile.get(callerFile);
|
|
81
|
+
if (local && local.has(name)) return local.get(name);
|
|
82
|
+
}
|
|
72
83
|
for (const m of byNameInFile.values()) {
|
|
73
84
|
if (m.has(name)) return m.get(name);
|
|
74
85
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Tree-sitter parser loader (roadmap #8) — OPTIONAL, runtime-lazy, degrades.
|
|
2
|
+
//
|
|
3
|
+
// web-tree-sitter + tree-sitter-wasms are OPTIONAL dependencies (pinned to an
|
|
4
|
+
// ABI-matched pair: web-tree-sitter 0.20.8 ↔ tree-sitter-wasms 0.1.13). They
|
|
5
|
+
// are NOT bundled into dist (the build marks them `--external`), so the
|
|
6
|
+
// committed bundle stays self-contained and small; this loader requires them
|
|
7
|
+
// lazily at runtime and returns null when they're absent. That keeps the
|
|
8
|
+
// scanner fully bootable offline / without the optional deps — long-tail
|
|
9
|
+
// languages simply fall back to the existing pattern detectors.
|
|
10
|
+
//
|
|
11
|
+
// Long-tail languages this unlocks (no first-class IR parser today):
|
|
12
|
+
// rust, solidity, cpp, c, go, swift, dart. (js/ts/py/java/etc. already have
|
|
13
|
+
// dedicated IR parsers and don't need this.)
|
|
14
|
+
|
|
15
|
+
import { createRequire } from 'node:module';
|
|
16
|
+
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
|
|
19
|
+
// language → prebuilt grammar wasm shipped by tree-sitter-wasms.
|
|
20
|
+
const GRAMMAR_WASM = {
|
|
21
|
+
rust: 'tree-sitter-rust.wasm',
|
|
22
|
+
solidity: 'tree-sitter-solidity.wasm',
|
|
23
|
+
cpp: 'tree-sitter-cpp.wasm',
|
|
24
|
+
c: 'tree-sitter-c.wasm',
|
|
25
|
+
go: 'tree-sitter-go.wasm',
|
|
26
|
+
swift: 'tree-sitter-swift.wasm',
|
|
27
|
+
dart: 'tree-sitter-dart.wasm',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const EXT_TO_LANG = {
|
|
31
|
+
rs: 'rust', sol: 'solidity', cpp: 'cpp', cc: 'cpp', cxx: 'cpp', hpp: 'cpp',
|
|
32
|
+
c: 'c', h: 'c', go: 'go', swift: 'swift', dart: 'dart',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function treeSitterLangOf(file) {
|
|
36
|
+
if (typeof file !== 'string') return null;
|
|
37
|
+
const ext = file.split('.').pop().toLowerCase();
|
|
38
|
+
return EXT_TO_LANG[ext] || null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let _Parser; // undefined = not tried, null = unavailable, fn = the class
|
|
42
|
+
let _initPromise = null;
|
|
43
|
+
const _langCache = new Map(); // language → Language | null
|
|
44
|
+
const _parserCache = new Map(); // language → Parser | null
|
|
45
|
+
|
|
46
|
+
async function _ensureRuntime() {
|
|
47
|
+
if (_Parser === null) return null;
|
|
48
|
+
if (_Parser) return _Parser;
|
|
49
|
+
try {
|
|
50
|
+
// 0.20 API: the module's default export IS the Parser class.
|
|
51
|
+
const mod = require('web-tree-sitter');
|
|
52
|
+
_Parser = mod && (mod.Parser || mod.default || mod);
|
|
53
|
+
if (!_initPromise) _initPromise = _Parser.init();
|
|
54
|
+
await _initPromise;
|
|
55
|
+
return _Parser;
|
|
56
|
+
} catch {
|
|
57
|
+
_Parser = null; // optional dep absent or failed to init → degrade.
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function _grammarPath(language) {
|
|
63
|
+
const file = GRAMMAR_WASM[language];
|
|
64
|
+
if (!file) return null;
|
|
65
|
+
try { return require.resolve('tree-sitter-wasms/out/' + file); } catch { return null; }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Returns a ready-to-use Parser for `language`, or null if tree-sitter or the
|
|
69
|
+
// grammar isn't available. Cached per language. `parser.parse(src)` is then
|
|
70
|
+
// synchronous, so callers can parse inside a sync loop after awaiting this.
|
|
71
|
+
export async function getParserFor(language) {
|
|
72
|
+
if (_parserCache.has(language)) return _parserCache.get(language);
|
|
73
|
+
const Parser = await _ensureRuntime();
|
|
74
|
+
if (!Parser) { _parserCache.set(language, null); return null; }
|
|
75
|
+
try {
|
|
76
|
+
let Lang = _langCache.get(language);
|
|
77
|
+
if (Lang === undefined) {
|
|
78
|
+
const wasm = _grammarPath(language);
|
|
79
|
+
Lang = wasm ? await Parser.Language.load(wasm) : null;
|
|
80
|
+
_langCache.set(language, Lang);
|
|
81
|
+
}
|
|
82
|
+
if (!Lang) { _parserCache.set(language, null); return null; }
|
|
83
|
+
const p = new Parser();
|
|
84
|
+
p.setLanguage(Lang);
|
|
85
|
+
_parserCache.set(language, p);
|
|
86
|
+
return p;
|
|
87
|
+
} catch {
|
|
88
|
+
_parserCache.set(language, null);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function isTreeSitterAvailable() {
|
|
94
|
+
return (await _ensureRuntime()) != null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Walk every named node, invoking cb(node). Iterative to avoid deep recursion.
|
|
98
|
+
export function walkNamed(root, cb) {
|
|
99
|
+
if (!root) return;
|
|
100
|
+
const stack = [root];
|
|
101
|
+
while (stack.length) {
|
|
102
|
+
const n = stack.pop();
|
|
103
|
+
cb(n);
|
|
104
|
+
for (let i = n.namedChildCount - 1; i >= 0; i--) stack.push(n.namedChild(i));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const _internals = { GRAMMAR_WASM, EXT_TO_LANG, _grammarPath };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Data Protection Impact Assessment (DPIA)
|
|
2
|
+
|
|
3
|
+
Generated by agentic-security scanner on 2026-05-31.
|
|
4
|
+
|
|
5
|
+
This is an automated DPIA scaffold derived from static analysis.
|
|
6
|
+
It must be reviewed and completed by a privacy officer before use.
|
|
7
|
+
|
|
8
|
+
## Data classes identified
|
|
9
|
+
|
|
10
|
+
## Privacy-related findings
|
|
11
|
+
|
|
12
|
+
| Severity | File:Line | Class → Sink | Description |
|
|
13
|
+
|---|---|---|---|
|
|
14
|
+
|
|
15
|
+
## Regulatory framework mapping
|
|
16
|
+
|
|
17
|
+
- **GDPR Art. 35** — DPIA required when processing is likely to result in high risk to data subjects.
|
|
18
|
+
- **CCPA §1798.130** — Notice + access rights for collected personal information.
|
|
19
|
+
|
|
20
|
+
## Reviewer checklist
|
|
21
|
+
|
|
22
|
+
- [ ] Confirm each PII field's collection has a documented lawful basis
|
|
23
|
+
- [ ] Confirm retention period for each class is documented
|
|
24
|
+
- [ ] Confirm DSAR (data subject access request) workflow exists
|
|
25
|
+
- [ ] Confirm encryption at rest + in transit for each class
|
|
26
|
+
- [ ] Confirm logging of PII access for audit (where applicable)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generatedAt": "2026-05-31T14:14:14.017Z",
|
|
3
|
+
"summary": {
|
|
4
|
+
"total": 1,
|
|
5
|
+
"hndlCritical": 0,
|
|
6
|
+
"standard": 1,
|
|
7
|
+
"filesAffected": 1,
|
|
8
|
+
"primitivesNeeded": [
|
|
9
|
+
"ML-DSA-65"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"milestones": [
|
|
13
|
+
{
|
|
14
|
+
"id": "M1",
|
|
15
|
+
"title": "Inventory & policy",
|
|
16
|
+
"target": "90 days",
|
|
17
|
+
"owner": "security",
|
|
18
|
+
"items": [
|
|
19
|
+
"Confirm scanner findings against design docs",
|
|
20
|
+
"Adopt PQC migration policy (CNSA 2.0 / NIST IR 8547 alignment)",
|
|
21
|
+
"Establish KMS support for hybrid keys"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "M2",
|
|
26
|
+
"title": "HNDL-critical paths to PQ-hybrid",
|
|
27
|
+
"target": "180 days",
|
|
28
|
+
"owner": "platform",
|
|
29
|
+
"items": []
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "M3",
|
|
33
|
+
"title": "Standard signing/KEX migration",
|
|
34
|
+
"target": "12 months",
|
|
35
|
+
"owner": "platform",
|
|
36
|
+
"items": [
|
|
37
|
+
{
|
|
38
|
+
"finding": "pqc-ed25519:rule-pack-signing.js:187",
|
|
39
|
+
"file": "rule-pack-signing.js",
|
|
40
|
+
"line": 187,
|
|
41
|
+
"replacement": "ML-DSA-65"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "M4",
|
|
47
|
+
"title": "Deprecate classical primitives",
|
|
48
|
+
"target": "24 months",
|
|
49
|
+
"owner": "security",
|
|
50
|
+
"items": [
|
|
51
|
+
"Remove dual-stack libraries once peers are PQ-capable",
|
|
52
|
+
"Rotate root CA / long-lived signing keys to ML-DSA"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"perFile": {
|
|
57
|
+
"rule-pack-signing.js": {
|
|
58
|
+
"count": 1,
|
|
59
|
+
"subfamilies": [
|
|
60
|
+
"pqc-ed25519"
|
|
61
|
+
],
|
|
62
|
+
"hndlCritical": false
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Post-quantum cryptography migration plan
|
|
2
|
+
|
|
3
|
+
Generated 2026-05-31.
|
|
4
|
+
|
|
5
|
+
**1** pre-quantum primitive sites across **1** files.
|
|
6
|
+
HNDL-critical: **0** | Standard: **1**
|
|
7
|
+
|
|
8
|
+
## Recommended PQ primitives
|
|
9
|
+
- ML-DSA-65
|
|
10
|
+
|
|
11
|
+
## M1 — Inventory & policy (target 90 days, owner security)
|
|
12
|
+
- Confirm scanner findings against design docs
|
|
13
|
+
- Adopt PQC migration policy (CNSA 2.0 / NIST IR 8547 alignment)
|
|
14
|
+
- Establish KMS support for hybrid keys
|
|
15
|
+
|
|
16
|
+
## M2 — HNDL-critical paths to PQ-hybrid (target 180 days, owner platform)
|
|
17
|
+
|
|
18
|
+
## M3 — Standard signing/KEX migration (target 12 months, owner platform)
|
|
19
|
+
- `rule-pack-signing.js:187` → ML-DSA-65
|
|
20
|
+
|
|
21
|
+
## M4 — Deprecate classical primitives (target 24 months, owner security)
|
|
22
|
+
- Remove dual-stack libraries once peers are PQ-capable
|
|
23
|
+
- Rotate root CA / long-lived signing keys to ML-DSA
|
|
24
|
+
|
|
25
|
+
## References
|
|
26
|
+
- NIST FIPS 203 (ML-KEM), FIPS 204 (ML-DSA), FIPS 205 (SLH-DSA)
|
|
27
|
+
- NIST IR 8547 — Transition to Post-Quantum Cryptographic Standards
|
|
28
|
+
- CNSA 2.0 — Commercial National Security Algorithm Suite, Sept 2022
|
|
29
|
+
- RFC 9794 — X25519MLKEM768 hybrid key exchange for TLS 1.3
|
|
30
|
+
- Open Quantum Safe project (liboqs, oqs-provider for OpenSSL 3)
|