@clear-capabilities/agentic-security-scanner 0.79.0 → 0.84.1

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.
Files changed (122) hide show
  1. package/dist/178.index.js +1 -1
  2. package/dist/333.index.js +283 -0
  3. package/dist/384.index.js +1 -1
  4. package/dist/637.index.js +1 -1
  5. package/dist/838.index.js +1 -1
  6. package/dist/839.index.js +170 -0
  7. package/dist/985.index.js +140 -1
  8. package/dist/agentic-security.mjs +10 -10
  9. package/dist/agentic-security.mjs.sha256 +1 -1
  10. package/package.json +7 -5
  11. package/src/.agentic-security/findings.json +117732 -0
  12. package/src/.agentic-security/last-scan.json +117732 -0
  13. package/src/.agentic-security/last-scan.json.sig +1 -0
  14. package/src/.agentic-security/scan-history.json +12946 -0
  15. package/src/.agentic-security/streak.json +21 -0
  16. package/src/dataflow/.agentic-security/findings.json +6086 -0
  17. package/src/dataflow/.agentic-security/last-scan.json +6086 -0
  18. package/src/dataflow/.agentic-security/last-scan.json.sig +1 -0
  19. package/src/dataflow/.agentic-security/scan-history.json +250 -0
  20. package/src/dataflow/.agentic-security/streak.json +21 -0
  21. package/src/dataflow/cross-service-taint.js +201 -0
  22. package/src/dataflow/formal-verify.js +204 -0
  23. package/src/dataflow/ifds-precise.js +222 -0
  24. package/src/dataflow/k2-summary-cache.js +153 -0
  25. package/src/dataflow/lib-taint-summaries.js +198 -0
  26. package/src/dataflow/privacy-taint.js +205 -0
  27. package/src/dataflow/smt-feasibility.js +189 -0
  28. package/src/engine.js +825 -127
  29. package/src/ir/.agentic-security/findings.json +4011 -0
  30. package/src/ir/.agentic-security/last-scan.json +4011 -0
  31. package/src/ir/.agentic-security/last-scan.json.sig +1 -0
  32. package/src/ir/.agentic-security/scan-history.json +193 -0
  33. package/src/ir/.agentic-security/streak.json +20 -0
  34. package/src/ir/cpp-preprocessor.js +142 -0
  35. package/src/ir/csharp-ir.js +604 -0
  36. package/src/ir/universal-ir.js +403 -0
  37. package/src/mcp/.agentic-security/findings.json +8632 -0
  38. package/src/mcp/.agentic-security/last-scan.json +8632 -0
  39. package/src/mcp/.agentic-security/last-scan.json.sig +1 -0
  40. package/src/mcp/.agentic-security/scan-history.json +331 -0
  41. package/src/mcp/.agentic-security/streak.json +20 -0
  42. package/src/mcp/tools.js +140 -1
  43. package/src/posture/.agentic-security/findings.json +77181 -0
  44. package/src/posture/.agentic-security/last-scan.json +77181 -0
  45. package/src/posture/.agentic-security/last-scan.json.sig +1 -0
  46. package/src/posture/.agentic-security/scan-history.json +8904 -0
  47. package/src/posture/.agentic-security/streak.json +21 -0
  48. package/src/posture/api-contract.js +193 -0
  49. package/src/posture/attack-taxonomy.js +227 -0
  50. package/src/posture/auditor-walkthrough.js +252 -0
  51. package/src/posture/claude-authorship.js +197 -0
  52. package/src/posture/compliance-frameworks/.agentic-security/findings.json +80 -0
  53. package/src/posture/compliance-frameworks/.agentic-security/last-scan.json +80 -0
  54. package/src/posture/compliance-frameworks/.agentic-security/last-scan.json.sig +1 -0
  55. package/src/posture/compliance-frameworks/.agentic-security/scan-history.json +90 -0
  56. package/src/posture/compliance-frameworks/.agentic-security/streak.json +22 -0
  57. package/src/posture/compliance-frameworks/ccpa.json +32 -0
  58. package/src/posture/compliance-frameworks/eu-ai-act.json +51 -0
  59. package/src/posture/compliance-frameworks/gdpr.json +45 -0
  60. package/src/posture/compliance-frameworks/hipaa-security-rule.json +56 -0
  61. package/src/posture/compliance-frameworks/nist-ai-600-1.json +51 -0
  62. package/src/posture/compliance-frameworks/nist-csf-2.json +73 -0
  63. package/src/posture/compliance-frameworks/owasp-asvs-5.json +79 -0
  64. package/src/posture/compliance-frameworks/owasp-llm-top-10.json +69 -0
  65. package/src/posture/compliance-policy.js +218 -0
  66. package/src/posture/composite-risk.js +122 -0
  67. package/src/posture/cross-repo-memory.js +180 -0
  68. package/src/posture/csharp-analysis.js +330 -0
  69. package/src/posture/dep-add-guard.js +197 -0
  70. package/src/posture/exploit-bundle.js +210 -0
  71. package/src/posture/federated-learning.js +172 -0
  72. package/src/posture/findings-memory.js +152 -0
  73. package/src/posture/fix-style-mirror.js +118 -0
  74. package/src/posture/git-history.js +141 -0
  75. package/src/posture/intent-context.js +175 -0
  76. package/src/posture/license-attributions.js +94 -0
  77. package/src/posture/license-graph.js +238 -0
  78. package/src/posture/model-rescan.js +76 -0
  79. package/src/posture/pattern-propagation.js +39 -0
  80. package/src/posture/pqc-migration-plan.js +158 -0
  81. package/src/posture/pr-augment.js +234 -0
  82. package/src/posture/reachability-filter.js +33 -2
  83. package/src/posture/realtime-cve-monitor.js +214 -0
  84. package/src/posture/risk-dollars.js +158 -0
  85. package/src/posture/runtime-correlation.js +174 -0
  86. package/src/posture/sbom-diff.js +171 -0
  87. package/src/posture/sca-policy.js +235 -0
  88. package/src/posture/sca-upgrade.js +259 -0
  89. package/src/posture/threat-model-auto.js +268 -0
  90. package/src/posture/threat-model-grounding.js +169 -0
  91. package/src/posture/time-to-fix.js +129 -0
  92. package/src/posture/triage-learning.js +170 -0
  93. package/src/posture/triage-memory.js +151 -0
  94. package/src/posture/triage.js +40 -1
  95. package/src/posture/watch-mode.js +171 -0
  96. package/src/posture/workflow-installer.js +231 -0
  97. package/src/sast/.agentic-security/findings.json +6154 -0
  98. package/src/sast/.agentic-security/last-scan.json +6154 -0
  99. package/src/sast/.agentic-security/last-scan.json.sig +1 -0
  100. package/src/sast/.agentic-security/scan-history.json +941 -0
  101. package/src/sast/.agentic-security/streak.json +22 -0
  102. package/src/sast/_secret-entropy.js +145 -0
  103. package/src/sast/cloud-iam.js +312 -0
  104. package/src/sast/cpp.js +138 -4
  105. package/src/sast/crypto-protocol.js +388 -0
  106. package/src/sast/csharp-tokenizer.js +392 -0
  107. package/src/sast/csharp.js +924 -138
  108. package/src/sast/dapp-frontend.js +200 -0
  109. package/src/sast/k8s-admission.js +271 -0
  110. package/src/sast/llm-app.js +272 -0
  111. package/src/sast/ml-supply-chain.js +259 -0
  112. package/src/sast/mobile.js +224 -0
  113. package/src/sast/post-quantum-crypto.js +348 -0
  114. package/src/sast/web3-advanced.js +375 -0
  115. package/src/sca/.agentic-security/findings.json +7460 -0
  116. package/src/sca/.agentic-security/last-scan.json +7460 -0
  117. package/src/sca/.agentic-security/last-scan.json.sig +1 -0
  118. package/src/sca/.agentic-security/scan-history.json +113 -0
  119. package/src/sca/.agentic-security/streak.json +21 -0
  120. package/src/sca/CLAUDE.md +161 -0
  121. package/src/sca/binary-metadata.js +37 -15
  122. package/src/sca/sigstore-verify.js +215 -0
@@ -0,0 +1 @@
1
+ c5c255f3078afcb3abb37615903b8ab5c7f13f82bd33a5089398909530ab25e9
@@ -0,0 +1,250 @@
1
+ [
2
+ {
3
+ "timestamp": "2026-05-28T21:51:05.438Z",
4
+ "label": "scan",
5
+ "total": 13,
6
+ "critical": 0,
7
+ "high": 0,
8
+ "medium": 13,
9
+ "low": 0,
10
+ "kev": 0,
11
+ "ids": [
12
+ "ssrf-meta-hardcoded:catalog.js:538",
13
+ "ssrf-meta-hardcoded:exploit-prover.js:33",
14
+ "struct:incremental.js:203:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
15
+ "struct:incremental.js:204:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
16
+ "struct:incremental.js:209:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
17
+ "struct:incremental.js:220:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
18
+ "struct:incremental.js:223:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
19
+ "struct:incremental.js:50:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
20
+ "struct:incremental.js:51:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
21
+ "struct:incremental.js:68:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
22
+ "struct:incremental.js:69:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
23
+ "toctou-fs:incremental.js:50",
24
+ "toctou-fs:incremental.js:68"
25
+ ]
26
+ },
27
+ {
28
+ "timestamp": "2026-05-28T21:58:02.385Z",
29
+ "label": "scan",
30
+ "total": 13,
31
+ "critical": 0,
32
+ "high": 0,
33
+ "medium": 13,
34
+ "low": 0,
35
+ "kev": 0,
36
+ "ids": [
37
+ "ssrf-meta-hardcoded:catalog.js:538",
38
+ "ssrf-meta-hardcoded:exploit-prover.js:33",
39
+ "struct:incremental.js:203:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
40
+ "struct:incremental.js:204:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
41
+ "struct:incremental.js:209:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
42
+ "struct:incremental.js:220:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
43
+ "struct:incremental.js:223:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
44
+ "struct:incremental.js:50:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
45
+ "struct:incremental.js:51:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
46
+ "struct:incremental.js:68:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
47
+ "struct:incremental.js:69:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
48
+ "toctou-fs:incremental.js:50",
49
+ "toctou-fs:incremental.js:68"
50
+ ]
51
+ },
52
+ {
53
+ "timestamp": "2026-05-29T06:25:27.255Z",
54
+ "label": "scan",
55
+ "total": 17,
56
+ "critical": 0,
57
+ "high": 0,
58
+ "medium": 17,
59
+ "low": 0,
60
+ "kev": 0,
61
+ "ids": [
62
+ "ssrf-meta-hardcoded:catalog.js:538",
63
+ "ssrf-meta-hardcoded:exploit-prover.js:33",
64
+ "struct:ifds-precise.js:177:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
65
+ "struct:ifds-precise.js:179:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
66
+ "struct:ifds-precise.js:206:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
67
+ "struct:incremental.js:203:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
68
+ "struct:incremental.js:204:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
69
+ "struct:incremental.js:209:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
70
+ "struct:incremental.js:220:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
71
+ "struct:incremental.js:223:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
72
+ "struct:incremental.js:50:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
73
+ "struct:incremental.js:51:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
74
+ "struct:incremental.js:68:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
75
+ "struct:incremental.js:69:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
76
+ "toctou-fs:ifds-precise.js:177",
77
+ "toctou-fs:incremental.js:50",
78
+ "toctou-fs:incremental.js:68"
79
+ ]
80
+ },
81
+ {
82
+ "timestamp": "2026-05-29T06:26:15.864Z",
83
+ "label": "scan",
84
+ "total": 17,
85
+ "critical": 0,
86
+ "high": 0,
87
+ "medium": 17,
88
+ "low": 0,
89
+ "kev": 0,
90
+ "ids": [
91
+ "ssrf-meta-hardcoded:catalog.js:538",
92
+ "ssrf-meta-hardcoded:exploit-prover.js:33",
93
+ "struct:ifds-precise.js:177:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
94
+ "struct:ifds-precise.js:179:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
95
+ "struct:ifds-precise.js:206:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
96
+ "struct:incremental.js:203:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
97
+ "struct:incremental.js:204:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
98
+ "struct:incremental.js:209:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
99
+ "struct:incremental.js:220:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
100
+ "struct:incremental.js:223:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
101
+ "struct:incremental.js:50:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
102
+ "struct:incremental.js:51:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
103
+ "struct:incremental.js:68:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
104
+ "struct:incremental.js:69:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
105
+ "toctou-fs:ifds-precise.js:177",
106
+ "toctou-fs:incremental.js:50",
107
+ "toctou-fs:incremental.js:68"
108
+ ]
109
+ },
110
+ {
111
+ "timestamp": "2026-05-29T06:26:55.369Z",
112
+ "label": "scan",
113
+ "total": 23,
114
+ "critical": 0,
115
+ "high": 0,
116
+ "medium": 23,
117
+ "low": 0,
118
+ "kev": 0,
119
+ "ids": [
120
+ "ssrf-meta-hardcoded:catalog.js:538",
121
+ "ssrf-meta-hardcoded:exploit-prover.js:33",
122
+ "struct:cross-service-taint.js:53:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
123
+ "struct:cross-service-taint.js:55:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
124
+ "struct:cross-service-taint.js:97:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
125
+ "struct:cross-service-taint.js:98:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
126
+ "struct:ifds-precise.js:177:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
127
+ "struct:ifds-precise.js:179:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
128
+ "struct:ifds-precise.js:206:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
129
+ "struct:incremental.js:203:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
130
+ "struct:incremental.js:204:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
131
+ "struct:incremental.js:209:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
132
+ "struct:incremental.js:220:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
133
+ "struct:incremental.js:223:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
134
+ "struct:incremental.js:50:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
135
+ "struct:incremental.js:51:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
136
+ "struct:incremental.js:68:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
137
+ "struct:incremental.js:69:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
138
+ "toctou-fs:cross-service-taint.js:53",
139
+ "toctou-fs:cross-service-taint.js:97",
140
+ "toctou-fs:ifds-precise.js:177",
141
+ "toctou-fs:incremental.js:50",
142
+ "toctou-fs:incremental.js:68"
143
+ ]
144
+ },
145
+ {
146
+ "timestamp": "2026-05-29T06:31:00.224Z",
147
+ "label": "scan",
148
+ "total": 23,
149
+ "critical": 0,
150
+ "high": 0,
151
+ "medium": 23,
152
+ "low": 0,
153
+ "kev": 0,
154
+ "ids": [
155
+ "ssrf-meta-hardcoded:catalog.js:538",
156
+ "ssrf-meta-hardcoded:exploit-prover.js:33",
157
+ "struct:cross-service-taint.js:53:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
158
+ "struct:cross-service-taint.js:55:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
159
+ "struct:cross-service-taint.js:97:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
160
+ "struct:cross-service-taint.js:98:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
161
+ "struct:ifds-precise.js:177:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
162
+ "struct:ifds-precise.js:179:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
163
+ "struct:ifds-precise.js:206:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
164
+ "struct:incremental.js:203:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
165
+ "struct:incremental.js:204:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
166
+ "struct:incremental.js:209:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
167
+ "struct:incremental.js:220:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
168
+ "struct:incremental.js:223:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
169
+ "struct:incremental.js:50:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
170
+ "struct:incremental.js:51:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
171
+ "struct:incremental.js:68:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
172
+ "struct:incremental.js:69:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
173
+ "toctou-fs:cross-service-taint.js:53",
174
+ "toctou-fs:cross-service-taint.js:97",
175
+ "toctou-fs:ifds-precise.js:177",
176
+ "toctou-fs:incremental.js:50",
177
+ "toctou-fs:incremental.js:68"
178
+ ]
179
+ },
180
+ {
181
+ "timestamp": "2026-05-29T06:32:47.791Z",
182
+ "label": "scan",
183
+ "total": 23,
184
+ "critical": 0,
185
+ "high": 0,
186
+ "medium": 23,
187
+ "low": 0,
188
+ "kev": 0,
189
+ "ids": [
190
+ "ssrf-meta-hardcoded:catalog.js:538",
191
+ "ssrf-meta-hardcoded:exploit-prover.js:33",
192
+ "struct:cross-service-taint.js:53:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
193
+ "struct:cross-service-taint.js:55:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
194
+ "struct:cross-service-taint.js:97:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
195
+ "struct:cross-service-taint.js:98:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
196
+ "struct:ifds-precise.js:177:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
197
+ "struct:ifds-precise.js:179:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
198
+ "struct:ifds-precise.js:206:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
199
+ "struct:incremental.js:203:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
200
+ "struct:incremental.js:204:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
201
+ "struct:incremental.js:209:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
202
+ "struct:incremental.js:220:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
203
+ "struct:incremental.js:223:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
204
+ "struct:incremental.js:50:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
205
+ "struct:incremental.js:51:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
206
+ "struct:incremental.js:68:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
207
+ "struct:incremental.js:69:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
208
+ "toctou-fs:cross-service-taint.js:53",
209
+ "toctou-fs:cross-service-taint.js:97",
210
+ "toctou-fs:ifds-precise.js:177",
211
+ "toctou-fs:incremental.js:50",
212
+ "toctou-fs:incremental.js:68"
213
+ ]
214
+ },
215
+ {
216
+ "timestamp": "2026-05-29T06:49:36.287Z",
217
+ "label": "scan",
218
+ "total": 23,
219
+ "critical": 0,
220
+ "high": 0,
221
+ "medium": 23,
222
+ "low": 0,
223
+ "kev": 0,
224
+ "ids": [
225
+ "ssrf-meta-hardcoded:catalog.js:538",
226
+ "ssrf-meta-hardcoded:exploit-prover.js:33",
227
+ "struct:cross-service-taint.js:53:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
228
+ "struct:cross-service-taint.js:55:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
229
+ "struct:cross-service-taint.js:97:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
230
+ "struct:cross-service-taint.js:98:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
231
+ "struct:ifds-precise.js:177:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
232
+ "struct:ifds-precise.js:179:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
233
+ "struct:ifds-precise.js:206:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
234
+ "struct:incremental.js:203:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
235
+ "struct:incremental.js:204:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
236
+ "struct:incremental.js:209:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
237
+ "struct:incremental.js:220:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
238
+ "struct:incremental.js:223:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
239
+ "struct:incremental.js:50:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
240
+ "struct:incremental.js:51:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
241
+ "struct:incremental.js:68:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
242
+ "struct:incremental.js:69:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
243
+ "toctou-fs:cross-service-taint.js:53",
244
+ "toctou-fs:cross-service-taint.js:97",
245
+ "toctou-fs:ifds-precise.js:177",
246
+ "toctou-fs:incremental.js:50",
247
+ "toctou-fs:incremental.js:68"
248
+ ]
249
+ }
250
+ ]
@@ -0,0 +1,21 @@
1
+ {
2
+ "firstScanDate": "2026-05-28T21:51:05.470Z",
3
+ "lastScanDate": "2026-05-29T06:49:36.319Z",
4
+ "totalScans": 8,
5
+ "daysCleanCritical": 2,
6
+ "lastCleanDate": "2026-05-29",
7
+ "lastCriticalDate": null,
8
+ "hasEverHadCritical": false,
9
+ "bestDaysCleanCritical": 2,
10
+ "totalFindingsAtFirstScan": 17,
11
+ "totalFindingsAtLastScan": 30,
12
+ "totalFixesInferred": 0,
13
+ "lastGrade": "A",
14
+ "bestGrade": "A",
15
+ "launchCheckPassedAt": null,
16
+ "achievements": [
17
+ "first-scan",
18
+ "grade-a"
19
+ ],
20
+ "previousGrade": "A"
21
+ }
@@ -0,0 +1,201 @@
1
+ // Cross-repo / cross-service taint — Recommendation #4 of the world-class
2
+ // roadmap.
3
+ //
4
+ // Discovers vulnerabilities that no single-repo scan can find: tainted
5
+ // data flowing from service A's HTTP request body, through A's response,
6
+ // into service B's consumer, then to a sink inside B. The "trust this
7
+ // because the upstream team owns it" assumption is what kills companies;
8
+ // the scanner catches it by reading a per-project service-graph file and
9
+ // propagating taint across service boundaries.
10
+ //
11
+ // Inputs:
12
+ // .agentic-security/services.yml — declares service-to-service edges:
13
+ //
14
+ // services:
15
+ // payments:
16
+ // repo: github.com/acme/payments
17
+ // exposes:
18
+ // - { route: "POST /charges", taints: ["request.amount", "request.cardToken"] }
19
+ // consumes:
20
+ // - { source: "events.charge_created", fields: ["amount", "cardToken"] }
21
+ // ledger:
22
+ // repo: github.com/acme/ledger
23
+ // exposes:
24
+ // - { route: "GET /balances/:userId", taints: ["pathParam.userId"] }
25
+ //
26
+ // edges:
27
+ // - { from: "payments", to: "ledger", via: "http", path: "/balances/{userId}" }
28
+ // - { from: "payments", to: "fraud", via: "kafka", topic: "events.charge_created" }
29
+ //
30
+ // The scanner uses this graph to:
31
+ // 1. Mark every "consumes" entry-point in each service as tainted-by-default
32
+ // 2. Walk the call graph from those entry points to any sink
33
+ // 3. When a finding's sink is reachable from a cross-service edge, emit a
34
+ // `crossService: { from, to, via, path }` annotation
35
+ // 4. Bump severity by one tier because cross-service taint is by definition
36
+ // reaching across a trust boundary
37
+ //
38
+ // In v1 we don't run BOTH services in one scan — that would require
39
+ // either a monorepo or a federated-scan API. We DO emit cross-service
40
+ // findings when the local service is on the receiving end of an edge,
41
+ // based on the declared upstream taint contract.
42
+
43
+ import * as fs from 'node:fs';
44
+ import * as path from 'node:path';
45
+ import * as yaml from 'js-yaml';
46
+
47
+ const SERVICES_FILE_NAMES = ['services.yml', 'services.yaml'];
48
+
49
+ export function loadServiceGraph(scanRoot) {
50
+ if (!scanRoot) return null;
51
+ for (const name of SERVICES_FILE_NAMES) {
52
+ const fp = path.join(scanRoot, '.agentic-security', name);
53
+ if (!fs.existsSync(fp)) continue;
54
+ try {
55
+ const raw = fs.readFileSync(fp, 'utf8');
56
+ const doc = yaml.load(raw);
57
+ return _normalizeGraph(doc);
58
+ } catch (e) {
59
+ return { _error: `Failed to parse ${fp}: ${e.message}` };
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+
65
+ function _normalizeGraph(doc) {
66
+ if (!doc || typeof doc !== 'object') return null;
67
+ const services = {};
68
+ for (const [name, def] of Object.entries(doc.services || {})) {
69
+ services[name] = {
70
+ name,
71
+ repo: def.repo || null,
72
+ exposes: Array.isArray(def.exposes) ? def.exposes : [],
73
+ consumes: Array.isArray(def.consumes) ? def.consumes : [],
74
+ };
75
+ }
76
+ const edges = Array.isArray(doc.edges) ? doc.edges.map(e => ({
77
+ from: e.from, to: e.to,
78
+ via: e.via || 'http',
79
+ path: e.path || null,
80
+ topic: e.topic || null,
81
+ })) : [];
82
+ return { services, edges };
83
+ }
84
+
85
+ /**
86
+ * Identify the "current service" by name. Two heuristics:
87
+ * 1. If the scanRoot's package.json / pyproject.toml / etc. name matches
88
+ * a service in the graph, that's us.
89
+ * 2. Otherwise fall back to the basename of the scanRoot.
90
+ */
91
+ export function identifyCurrentService(graph, scanRoot) {
92
+ if (!graph || !graph.services) return null;
93
+ // Try package.json / pyproject.toml name field.
94
+ let projectName = null;
95
+ try {
96
+ const pkg = path.join(scanRoot, 'package.json');
97
+ if (fs.existsSync(pkg)) {
98
+ const j = JSON.parse(fs.readFileSync(pkg, 'utf8'));
99
+ projectName = j.name;
100
+ }
101
+ } catch {}
102
+ if (projectName && graph.services[projectName]) return graph.services[projectName];
103
+ const base = path.basename(scanRoot);
104
+ if (graph.services[base]) return graph.services[base];
105
+ return null;
106
+ }
107
+
108
+ /**
109
+ * Compute the list of incoming "edges" terminating at the current
110
+ * service. Each edge identifies which upstream service is the source of
111
+ * taint into this service.
112
+ */
113
+ export function incomingEdges(graph, currentService) {
114
+ if (!graph || !currentService) return [];
115
+ return (graph.edges || []).filter(e => e.to === currentService.name);
116
+ }
117
+
118
+ /**
119
+ * For each consume entry on the current service, locate the upstream
120
+ * `exposes` entry that produces it (matched by path/topic) and return
121
+ * the upstream-declared tainted fields. This is the data we use to
122
+ * mark code entry points as tainted-by-default during scanning.
123
+ */
124
+ export function upstreamTaintContract(graph, currentService) {
125
+ if (!graph || !currentService) return [];
126
+ const contracts = [];
127
+ for (const consume of currentService.consumes || []) {
128
+ for (const edge of (graph.edges || [])) {
129
+ if (edge.to !== currentService.name) continue;
130
+ const upstream = graph.services[edge.from];
131
+ if (!upstream) continue;
132
+ for (const expose of upstream.exposes || []) {
133
+ const matches = (edge.via === 'http' && edge.path && expose.route && expose.route.includes(edge.path.split('?')[0]))
134
+ || (edge.via === 'kafka' && edge.topic && consume.source === edge.topic);
135
+ if (matches) {
136
+ contracts.push({
137
+ upstreamService: upstream.name,
138
+ via: edge.via,
139
+ taintedFields: [...(consume.fields || []), ...(expose.taints || [])],
140
+ consume,
141
+ expose,
142
+ });
143
+ }
144
+ }
145
+ }
146
+ }
147
+ return contracts;
148
+ }
149
+
150
+ /**
151
+ * Annotate findings whose source matches a cross-service taint contract.
152
+ * Adds `crossService: { from, via, path, taintedFields }` and bumps
153
+ * severity by one tier (medium → high, high → critical).
154
+ */
155
+ export function annotateCrossServiceFindings(findings, graph, currentService) {
156
+ if (!Array.isArray(findings) || !graph || !currentService) return { annotated: 0, bumped: 0 };
157
+ const contracts = upstreamTaintContract(graph, currentService);
158
+ if (!contracts.length) return { annotated: 0, bumped: 0 };
159
+ let annotated = 0, bumped = 0;
160
+ for (const f of findings) {
161
+ const sourceExpr = (f.source && (f.source.snippet || f.source.expr)) || f.snippet || '';
162
+ for (const contract of contracts) {
163
+ const matches = contract.taintedFields.some(field => {
164
+ const pat = new RegExp(`\\b${field.replace('.', '\\.')}\\b`);
165
+ return pat.test(sourceExpr);
166
+ });
167
+ if (!matches) continue;
168
+ f.crossService = {
169
+ from: contract.upstreamService,
170
+ to: currentService.name,
171
+ via: contract.via,
172
+ taintedField: contract.taintedFields.find(field => new RegExp(`\\b${field.replace('.', '\\.')}\\b`).test(sourceExpr)),
173
+ };
174
+ annotated++;
175
+ // Severity bump.
176
+ const ladder = ['info', 'low', 'medium', 'high', 'critical'];
177
+ const cur = ladder.indexOf(f.severity);
178
+ if (cur > 0 && cur < ladder.length - 1) {
179
+ f._severityBumpReason = `cross-service-from:${contract.upstreamService}`;
180
+ f.severity = ladder[cur + 1];
181
+ bumped++;
182
+ }
183
+ break;
184
+ }
185
+ }
186
+ return { annotated, bumped };
187
+ }
188
+
189
+ /**
190
+ * Run the cross-service annotation pass — convenience entry point called
191
+ * from the engine after the normal scan completes.
192
+ */
193
+ export function runCrossServiceTaint(scanRoot, findings) {
194
+ const graph = loadServiceGraph(scanRoot);
195
+ if (!graph || graph._error) return { error: graph?._error, annotated: 0 };
196
+ const current = identifyCurrentService(graph, scanRoot);
197
+ if (!current) return { error: 'no-current-service-identified', annotated: 0 };
198
+ return annotateCrossServiceFindings(findings, graph, current);
199
+ }
200
+
201
+ export const _internals = { _normalizeGraph, SERVICES_FILE_NAMES };