@clear-capabilities/agentic-security-scanner 0.75.0 → 0.77.0

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 (68) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/bin/agentic-security.js +2 -2
  3. package/dist/838.index.js +152 -0
  4. package/dist/{634.index.js → 985.index.js} +21 -144
  5. package/dist/agentic-security.mjs +8 -8
  6. package/dist/agentic-security.mjs.sha256 +1 -1
  7. package/package.json +6 -6
  8. package/src/mcp/tools.js +17 -2
  9. package/src/sca/base-images.json +1 -1
  10. package/bin/.agentic-security/findings.json +0 -1596
  11. package/bin/.agentic-security/last-scan.json +0 -1596
  12. package/bin/.agentic-security/last-scan.json.sig +0 -1
  13. package/bin/.agentic-security/scan-history.json +0 -470
  14. package/bin/.agentic-security/streak.json +0 -25
  15. package/dist/218.index.js +0 -793
  16. package/dist/601.index.js +0 -1038
  17. package/src/.agentic-security/findings.json +0 -80844
  18. package/src/.agentic-security/last-scan.json +0 -80844
  19. package/src/.agentic-security/last-scan.json.sig +0 -1
  20. package/src/.agentic-security/scan-history.json +0 -8408
  21. package/src/.agentic-security/streak.json +0 -26
  22. package/src/dataflow/.agentic-security/findings.json +0 -3487
  23. package/src/dataflow/.agentic-security/last-scan.json +0 -3487
  24. package/src/dataflow/.agentic-security/last-scan.json.sig +0 -1
  25. package/src/dataflow/.agentic-security/scan-history.json +0 -735
  26. package/src/dataflow/.agentic-security/streak.json +0 -24
  27. package/src/integrations/.agentic-security/findings.json +0 -1504
  28. package/src/integrations/.agentic-security/last-scan.json +0 -1504
  29. package/src/integrations/.agentic-security/scan-history.json +0 -40
  30. package/src/integrations/.agentic-security/streak.json +0 -21
  31. package/src/ir/.agentic-security/findings.json +0 -3036
  32. package/src/ir/.agentic-security/last-scan.json +0 -3036
  33. package/src/ir/.agentic-security/last-scan.json.sig +0 -1
  34. package/src/ir/.agentic-security/scan-history.json +0 -364
  35. package/src/ir/.agentic-security/streak.json +0 -23
  36. package/src/llm-validator/.agentic-security/findings.json +0 -1891
  37. package/src/llm-validator/.agentic-security/last-scan.json +0 -1891
  38. package/src/llm-validator/.agentic-security/last-scan.json.sig +0 -1
  39. package/src/llm-validator/.agentic-security/scan-history.json +0 -168
  40. package/src/llm-validator/.agentic-security/streak.json +0 -20
  41. package/src/lsp/.agentic-security/findings.json +0 -28
  42. package/src/lsp/.agentic-security/last-scan.json +0 -28
  43. package/src/lsp/.agentic-security/scan-history.json +0 -79
  44. package/src/lsp/.agentic-security/streak.json +0 -22
  45. package/src/mcp/.agentic-security/findings.json +0 -8358
  46. package/src/mcp/.agentic-security/last-scan.json +0 -8358
  47. package/src/mcp/.agentic-security/last-scan.json.sig +0 -1
  48. package/src/mcp/.agentic-security/scan-history.json +0 -1125
  49. package/src/mcp/.agentic-security/streak.json +0 -22
  50. package/src/posture/.agentic-security/findings.json +0 -51239
  51. package/src/posture/.agentic-security/last-scan.json +0 -51239
  52. package/src/posture/.agentic-security/last-scan.json.sig +0 -1
  53. package/src/posture/.agentic-security/scan-history.json +0 -5557
  54. package/src/posture/.agentic-security/streak.json +0 -24
  55. package/src/report/.agentic-security/findings.json +0 -79
  56. package/src/report/.agentic-security/last-scan.json +0 -79
  57. package/src/report/.agentic-security/last-scan.json.sig +0 -1
  58. package/src/report/.agentic-security/scan-history.json +0 -332
  59. package/src/report/.agentic-security/streak.json +0 -23
  60. package/src/sast/.agentic-security/findings.json +0 -5051
  61. package/src/sast/.agentic-security/last-scan.json +0 -5051
  62. package/src/sast/.agentic-security/last-scan.json.sig +0 -1
  63. package/src/sast/.agentic-security/scan-history.json +0 -788
  64. package/src/sast/.agentic-security/streak.json +0 -23
  65. package/src/sast/bench-shape/.agentic-security/findings.json +0 -28
  66. package/src/sast/bench-shape/.agentic-security/last-scan.json +0 -28
  67. package/src/sast/bench-shape/.agentic-security/scan-history.json +0 -24
  68. package/src/sast/bench-shape/.agentic-security/streak.json +0 -22
@@ -1,1504 +0,0 @@
1
- {
2
- "scanId": "25ac4913-94b8-4713-a870-a7e371a6540e",
3
- "startedAt": "2026-05-18T17:50:17.286Z",
4
- "durationMs": 109,
5
- "scanned": {
6
- "files": 2,
7
- "lines": 0
8
- },
9
- "findings": [
10
- {
11
- "id": "struct:index.js:23:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
12
- "kind": "sast",
13
- "severity": "medium",
14
- "vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
15
- "cwe": "CWE-400",
16
- "owaspLlm": null,
17
- "stride": "Denial of Service",
18
- "file": "index.js",
19
- "line": 23,
20
- "snippet": "if (!fs.existsSync(fp)) return {};",
21
- "fix": null,
22
- "reachable": false,
23
- "triage": 22,
24
- "dataClasses": [],
25
- "chain": null,
26
- "confidence": null,
27
- "toxicity": 28,
28
- "toxicityFactors": [
29
- "http-facing"
30
- ],
31
- "toxicityLabel": "Medium",
32
- "sources": null,
33
- "epssScore": null,
34
- "epssPercentile": null,
35
- "epssCve": null,
36
- "exploitedNow": false,
37
- "tags": null,
38
- "blastRadius": {
39
- "scope": "all-users",
40
- "dataAtRisk": [
41
- "config"
42
- ],
43
- "userCount": 50,
44
- "industry": "generic",
45
- "jurisdictions": [],
46
- "controlsApplied": [],
47
- "dollarBest": 23250,
48
- "dollarLikely": 136250,
49
- "dollarWorst": 775000,
50
- "dollarLow": 23250,
51
- "dollarHigh": 775000,
52
- "components": {
53
- "incidentResponse": {
54
- "low": 8000,
55
- "likely": 50000,
56
- "high": 250000
57
- },
58
- "legal": {
59
- "low": 10000,
60
- "likely": 75000,
61
- "high": 500000
62
- },
63
- "crisisPR": {
64
- "low": 0,
65
- "likely": 0,
66
- "high": 0
67
- },
68
- "notification": {
69
- "low": 5000,
70
- "likely": 10000,
71
- "high": 15000
72
- },
73
- "creditMonitoring": {
74
- "low": 0,
75
- "likely": 0,
76
- "high": 0
77
- },
78
- "regulatoryFines": {
79
- "low": 0,
80
- "likely": 0,
81
- "high": 0
82
- },
83
- "directDamage": {
84
- "low": 250,
85
- "likely": 1250,
86
- "high": 10000
87
- },
88
- "classAction": {
89
- "low": 0,
90
- "likely": 0,
91
- "high": 0
92
- },
93
- "lostBusiness": {
94
- "low": 0,
95
- "likely": 0,
96
- "high": 0
97
- }
98
- },
99
- "dominantDriver": "legal counsel",
100
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
101
- "confidence": "low",
102
- "narrative": "Synchronous Blocking I/O (DoS Risk in Server Context) on `index.js:23` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
103
- }
104
- },
105
- {
106
- "id": "struct:index.js:24:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
107
- "kind": "sast",
108
- "severity": "medium",
109
- "vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
110
- "cwe": "CWE-400",
111
- "owaspLlm": null,
112
- "stride": "Denial of Service",
113
- "file": "index.js",
114
- "line": 24,
115
- "snippet": "try { return yaml.load(fs.readFileSync(fp, 'utf8')) || {}; }",
116
- "fix": null,
117
- "reachable": false,
118
- "triage": 22,
119
- "dataClasses": [],
120
- "chain": null,
121
- "confidence": null,
122
- "toxicity": 28,
123
- "toxicityFactors": [
124
- "http-facing"
125
- ],
126
- "toxicityLabel": "Medium",
127
- "sources": null,
128
- "epssScore": null,
129
- "epssPercentile": null,
130
- "epssCve": null,
131
- "exploitedNow": false,
132
- "tags": null,
133
- "blastRadius": {
134
- "scope": "all-users",
135
- "dataAtRisk": [
136
- "config"
137
- ],
138
- "userCount": 50,
139
- "industry": "generic",
140
- "jurisdictions": [],
141
- "controlsApplied": [],
142
- "dollarBest": 23250,
143
- "dollarLikely": 136250,
144
- "dollarWorst": 775000,
145
- "dollarLow": 23250,
146
- "dollarHigh": 775000,
147
- "components": {
148
- "incidentResponse": {
149
- "low": 8000,
150
- "likely": 50000,
151
- "high": 250000
152
- },
153
- "legal": {
154
- "low": 10000,
155
- "likely": 75000,
156
- "high": 500000
157
- },
158
- "crisisPR": {
159
- "low": 0,
160
- "likely": 0,
161
- "high": 0
162
- },
163
- "notification": {
164
- "low": 5000,
165
- "likely": 10000,
166
- "high": 15000
167
- },
168
- "creditMonitoring": {
169
- "low": 0,
170
- "likely": 0,
171
- "high": 0
172
- },
173
- "regulatoryFines": {
174
- "low": 0,
175
- "likely": 0,
176
- "high": 0
177
- },
178
- "directDamage": {
179
- "low": 250,
180
- "likely": 1250,
181
- "high": 10000
182
- },
183
- "classAction": {
184
- "low": 0,
185
- "likely": 0,
186
- "high": 0
187
- },
188
- "lostBusiness": {
189
- "low": 0,
190
- "likely": 0,
191
- "high": 0
192
- }
193
- },
194
- "dominantDriver": "legal counsel",
195
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
196
- "confidence": "low",
197
- "narrative": "Synchronous Blocking I/O (DoS Risk in Server Context) on `index.js:24` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
198
- }
199
- },
200
- {
201
- "id": "struct:tickets.js:26:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
202
- "kind": "sast",
203
- "severity": "medium",
204
- "vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
205
- "cwe": "CWE-400",
206
- "owaspLlm": null,
207
- "stride": "Denial of Service",
208
- "file": "tickets.js",
209
- "line": 26,
210
- "snippet": "if (!fs.existsSync(fp)) return {};",
211
- "fix": null,
212
- "reachable": false,
213
- "triage": 22,
214
- "dataClasses": [],
215
- "chain": null,
216
- "confidence": null,
217
- "toxicity": 28,
218
- "toxicityFactors": [
219
- "http-facing"
220
- ],
221
- "toxicityLabel": "Medium",
222
- "sources": null,
223
- "epssScore": null,
224
- "epssPercentile": null,
225
- "epssCve": null,
226
- "exploitedNow": false,
227
- "tags": null,
228
- "blastRadius": {
229
- "scope": "all-users",
230
- "dataAtRisk": [
231
- "config"
232
- ],
233
- "userCount": 50,
234
- "industry": "generic",
235
- "jurisdictions": [],
236
- "controlsApplied": [],
237
- "dollarBest": 23250,
238
- "dollarLikely": 136250,
239
- "dollarWorst": 775000,
240
- "dollarLow": 23250,
241
- "dollarHigh": 775000,
242
- "components": {
243
- "incidentResponse": {
244
- "low": 8000,
245
- "likely": 50000,
246
- "high": 250000
247
- },
248
- "legal": {
249
- "low": 10000,
250
- "likely": 75000,
251
- "high": 500000
252
- },
253
- "crisisPR": {
254
- "low": 0,
255
- "likely": 0,
256
- "high": 0
257
- },
258
- "notification": {
259
- "low": 5000,
260
- "likely": 10000,
261
- "high": 15000
262
- },
263
- "creditMonitoring": {
264
- "low": 0,
265
- "likely": 0,
266
- "high": 0
267
- },
268
- "regulatoryFines": {
269
- "low": 0,
270
- "likely": 0,
271
- "high": 0
272
- },
273
- "directDamage": {
274
- "low": 250,
275
- "likely": 1250,
276
- "high": 10000
277
- },
278
- "classAction": {
279
- "low": 0,
280
- "likely": 0,
281
- "high": 0
282
- },
283
- "lostBusiness": {
284
- "low": 0,
285
- "likely": 0,
286
- "high": 0
287
- }
288
- },
289
- "dominantDriver": "legal counsel",
290
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
291
- "confidence": "low",
292
- "narrative": "Synchronous Blocking I/O (DoS Risk in Server Context) on `tickets.js:26` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
293
- }
294
- },
295
- {
296
- "id": "struct:tickets.js:27:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
297
- "kind": "sast",
298
- "severity": "medium",
299
- "vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
300
- "cwe": "CWE-400",
301
- "owaspLlm": null,
302
- "stride": "Denial of Service",
303
- "file": "tickets.js",
304
- "line": 27,
305
- "snippet": "try { return JSON.parse(fs.readFileSync(fp, 'utf8')); } catch { return {}; }",
306
- "fix": null,
307
- "reachable": false,
308
- "triage": 22,
309
- "dataClasses": [],
310
- "chain": null,
311
- "confidence": null,
312
- "toxicity": 28,
313
- "toxicityFactors": [
314
- "http-facing"
315
- ],
316
- "toxicityLabel": "Medium",
317
- "sources": null,
318
- "epssScore": null,
319
- "epssPercentile": null,
320
- "epssCve": null,
321
- "exploitedNow": false,
322
- "tags": null,
323
- "blastRadius": {
324
- "scope": "all-users",
325
- "dataAtRisk": [
326
- "config"
327
- ],
328
- "userCount": 50,
329
- "industry": "generic",
330
- "jurisdictions": [],
331
- "controlsApplied": [],
332
- "dollarBest": 23250,
333
- "dollarLikely": 136250,
334
- "dollarWorst": 775000,
335
- "dollarLow": 23250,
336
- "dollarHigh": 775000,
337
- "components": {
338
- "incidentResponse": {
339
- "low": 8000,
340
- "likely": 50000,
341
- "high": 250000
342
- },
343
- "legal": {
344
- "low": 10000,
345
- "likely": 75000,
346
- "high": 500000
347
- },
348
- "crisisPR": {
349
- "low": 0,
350
- "likely": 0,
351
- "high": 0
352
- },
353
- "notification": {
354
- "low": 5000,
355
- "likely": 10000,
356
- "high": 15000
357
- },
358
- "creditMonitoring": {
359
- "low": 0,
360
- "likely": 0,
361
- "high": 0
362
- },
363
- "regulatoryFines": {
364
- "low": 0,
365
- "likely": 0,
366
- "high": 0
367
- },
368
- "directDamage": {
369
- "low": 250,
370
- "likely": 1250,
371
- "high": 10000
372
- },
373
- "classAction": {
374
- "low": 0,
375
- "likely": 0,
376
- "high": 0
377
- },
378
- "lostBusiness": {
379
- "low": 0,
380
- "likely": 0,
381
- "high": 0
382
- }
383
- },
384
- "dominantDriver": "legal counsel",
385
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
386
- "confidence": "low",
387
- "narrative": "Synchronous Blocking I/O (DoS Risk in Server Context) on `tickets.js:27` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
388
- }
389
- },
390
- {
391
- "id": "struct:tickets.js:31:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
392
- "kind": "sast",
393
- "severity": "medium",
394
- "vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
395
- "cwe": "CWE-400",
396
- "owaspLlm": null,
397
- "stride": "Denial of Service",
398
- "file": "tickets.js",
399
- "line": 31,
400
- "snippet": "fs.writeFileSync(statePath(scanRoot), JSON.stringify(state, null, 2));",
401
- "fix": null,
402
- "reachable": false,
403
- "triage": 22,
404
- "dataClasses": [],
405
- "chain": null,
406
- "confidence": null,
407
- "toxicity": 28,
408
- "toxicityFactors": [
409
- "http-facing"
410
- ],
411
- "toxicityLabel": "Medium",
412
- "sources": null,
413
- "epssScore": null,
414
- "epssPercentile": null,
415
- "epssCve": null,
416
- "exploitedNow": false,
417
- "tags": null,
418
- "blastRadius": {
419
- "scope": "all-users",
420
- "dataAtRisk": [
421
- "config"
422
- ],
423
- "userCount": 50,
424
- "industry": "generic",
425
- "jurisdictions": [],
426
- "controlsApplied": [],
427
- "dollarBest": 23250,
428
- "dollarLikely": 136250,
429
- "dollarWorst": 775000,
430
- "dollarLow": 23250,
431
- "dollarHigh": 775000,
432
- "components": {
433
- "incidentResponse": {
434
- "low": 8000,
435
- "likely": 50000,
436
- "high": 250000
437
- },
438
- "legal": {
439
- "low": 10000,
440
- "likely": 75000,
441
- "high": 500000
442
- },
443
- "crisisPR": {
444
- "low": 0,
445
- "likely": 0,
446
- "high": 0
447
- },
448
- "notification": {
449
- "low": 5000,
450
- "likely": 10000,
451
- "high": 15000
452
- },
453
- "creditMonitoring": {
454
- "low": 0,
455
- "likely": 0,
456
- "high": 0
457
- },
458
- "regulatoryFines": {
459
- "low": 0,
460
- "likely": 0,
461
- "high": 0
462
- },
463
- "directDamage": {
464
- "low": 250,
465
- "likely": 1250,
466
- "high": 10000
467
- },
468
- "classAction": {
469
- "low": 0,
470
- "likely": 0,
471
- "high": 0
472
- },
473
- "lostBusiness": {
474
- "low": 0,
475
- "likely": 0,
476
- "high": 0
477
- }
478
- },
479
- "dominantDriver": "legal counsel",
480
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
481
- "confidence": "low",
482
- "narrative": "Synchronous Blocking I/O (DoS Risk in Server Context) on `tickets.js:31` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
483
- }
484
- },
485
- {
486
- "id": "struct:tickets.js:146:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
487
- "kind": "sast",
488
- "severity": "medium",
489
- "vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
490
- "cwe": "CWE-400",
491
- "owaspLlm": null,
492
- "stride": "Denial of Service",
493
- "file": "tickets.js",
494
- "line": 146,
495
- "snippet": "if (!fs.existsSync(lastScanPath)) return { ok: false, error: 'no last-scan.json — run a scan first' };",
496
- "fix": null,
497
- "reachable": false,
498
- "triage": 22,
499
- "dataClasses": [],
500
- "chain": null,
501
- "confidence": null,
502
- "toxicity": 28,
503
- "toxicityFactors": [
504
- "http-facing"
505
- ],
506
- "toxicityLabel": "Medium",
507
- "sources": null,
508
- "epssScore": null,
509
- "epssPercentile": null,
510
- "epssCve": null,
511
- "exploitedNow": false,
512
- "tags": null,
513
- "blastRadius": {
514
- "scope": "all-users",
515
- "dataAtRisk": [
516
- "config"
517
- ],
518
- "userCount": 50,
519
- "industry": "generic",
520
- "jurisdictions": [],
521
- "controlsApplied": [],
522
- "dollarBest": 23250,
523
- "dollarLikely": 136250,
524
- "dollarWorst": 775000,
525
- "dollarLow": 23250,
526
- "dollarHigh": 775000,
527
- "components": {
528
- "incidentResponse": {
529
- "low": 8000,
530
- "likely": 50000,
531
- "high": 250000
532
- },
533
- "legal": {
534
- "low": 10000,
535
- "likely": 75000,
536
- "high": 500000
537
- },
538
- "crisisPR": {
539
- "low": 0,
540
- "likely": 0,
541
- "high": 0
542
- },
543
- "notification": {
544
- "low": 5000,
545
- "likely": 10000,
546
- "high": 15000
547
- },
548
- "creditMonitoring": {
549
- "low": 0,
550
- "likely": 0,
551
- "high": 0
552
- },
553
- "regulatoryFines": {
554
- "low": 0,
555
- "likely": 0,
556
- "high": 0
557
- },
558
- "directDamage": {
559
- "low": 250,
560
- "likely": 1250,
561
- "high": 10000
562
- },
563
- "classAction": {
564
- "low": 0,
565
- "likely": 0,
566
- "high": 0
567
- },
568
- "lostBusiness": {
569
- "low": 0,
570
- "likely": 0,
571
- "high": 0
572
- }
573
- },
574
- "dominantDriver": "legal counsel",
575
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
576
- "confidence": "low",
577
- "narrative": "Synchronous Blocking I/O (DoS Risk in Server Context) on `tickets.js:146` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
578
- }
579
- },
580
- {
581
- "id": "struct:tickets.js:147:Synchronous_Blocking_I/O_(DoS_Risk_in_Server_Context)",
582
- "kind": "sast",
583
- "severity": "medium",
584
- "vuln": "Synchronous Blocking I/O (DoS Risk in Server Context)",
585
- "cwe": "CWE-400",
586
- "owaspLlm": null,
587
- "stride": "Denial of Service",
588
- "file": "tickets.js",
589
- "line": 147,
590
- "snippet": "const last = JSON.parse(fs.readFileSync(lastScanPath, 'utf8'));",
591
- "fix": null,
592
- "reachable": false,
593
- "triage": 22,
594
- "dataClasses": [],
595
- "chain": null,
596
- "confidence": null,
597
- "toxicity": 28,
598
- "toxicityFactors": [
599
- "http-facing"
600
- ],
601
- "toxicityLabel": "Medium",
602
- "sources": null,
603
- "epssScore": null,
604
- "epssPercentile": null,
605
- "epssCve": null,
606
- "exploitedNow": false,
607
- "tags": null,
608
- "blastRadius": {
609
- "scope": "all-users",
610
- "dataAtRisk": [
611
- "config"
612
- ],
613
- "userCount": 50,
614
- "industry": "generic",
615
- "jurisdictions": [],
616
- "controlsApplied": [],
617
- "dollarBest": 23250,
618
- "dollarLikely": 136250,
619
- "dollarWorst": 775000,
620
- "dollarLow": 23250,
621
- "dollarHigh": 775000,
622
- "components": {
623
- "incidentResponse": {
624
- "low": 8000,
625
- "likely": 50000,
626
- "high": 250000
627
- },
628
- "legal": {
629
- "low": 10000,
630
- "likely": 75000,
631
- "high": 500000
632
- },
633
- "crisisPR": {
634
- "low": 0,
635
- "likely": 0,
636
- "high": 0
637
- },
638
- "notification": {
639
- "low": 5000,
640
- "likely": 10000,
641
- "high": 15000
642
- },
643
- "creditMonitoring": {
644
- "low": 0,
645
- "likely": 0,
646
- "high": 0
647
- },
648
- "regulatoryFines": {
649
- "low": 0,
650
- "likely": 0,
651
- "high": 0
652
- },
653
- "directDamage": {
654
- "low": 250,
655
- "likely": 1250,
656
- "high": 10000
657
- },
658
- "classAction": {
659
- "low": 0,
660
- "likely": 0,
661
- "high": 0
662
- },
663
- "lostBusiness": {
664
- "low": 0,
665
- "likely": 0,
666
- "high": 0
667
- }
668
- },
669
- "dominantDriver": "legal counsel",
670
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
671
- "confidence": "low",
672
- "narrative": "Synchronous Blocking I/O (DoS Risk in Server Context) on `tickets.js:147` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
673
- }
674
- },
675
- {
676
- "id": "b4961817017f5422",
677
- "kind": "logic",
678
- "severity": "medium",
679
- "vuln": "Timing Oracle — Non-Constant-Time Secret Comparison",
680
- "cwe": "CWE-208",
681
- "stride": "Information Disclosure",
682
- "file": "index.js",
683
- "line": 81,
684
- "snippet": "if (!url || process.env.AGENTIC_SECURITY_OFFLINE === '1') return { ok: false, reason: 'offline-or-no-url' };",
685
- "fix": {
686
- "description": "Use crypto.timingSafeEqual() for all comparisons involving secrets or API keys.",
687
- "code": "// BEFORE\nif (req.headers['x-api-key'] === process.env.API_KEY) { ... }\n\n// AFTER\nconst a = Buffer.from(req.headers['x-api-key'] || '');\nconst b = Buffer.from(process.env.API_KEY || '');\nif (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.status(401);"
688
- },
689
- "blastRadius": {
690
- "scope": "all-users",
691
- "dataAtRisk": [
692
- "credentials"
693
- ],
694
- "userCount": 50,
695
- "industry": "generic",
696
- "jurisdictions": [],
697
- "controlsApplied": [],
698
- "dollarBest": 24000,
699
- "dollarLikely": 138000,
700
- "dollarWorst": 777500,
701
- "dollarLow": 24000,
702
- "dollarHigh": 777500,
703
- "components": {
704
- "incidentResponse": {
705
- "low": 8000,
706
- "likely": 50000,
707
- "high": 250000
708
- },
709
- "legal": {
710
- "low": 10000,
711
- "likely": 75000,
712
- "high": 500000
713
- },
714
- "crisisPR": {
715
- "low": 0,
716
- "likely": 0,
717
- "high": 0
718
- },
719
- "notification": {
720
- "low": 5000,
721
- "likely": 10000,
722
- "high": 15000
723
- },
724
- "creditMonitoring": {
725
- "low": 0,
726
- "likely": 0,
727
- "high": 0
728
- },
729
- "regulatoryFines": {
730
- "low": 0,
731
- "likely": 0,
732
- "high": 0
733
- },
734
- "directDamage": {
735
- "low": 1000,
736
- "likely": 3000,
737
- "high": 12500
738
- },
739
- "classAction": {
740
- "low": 0,
741
- "likely": 0,
742
- "high": 0
743
- },
744
- "lostBusiness": {
745
- "low": 0,
746
- "likely": 0,
747
- "high": 0
748
- }
749
- },
750
- "dominantDriver": "legal counsel",
751
- "comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
752
- "confidence": "low",
753
- "narrative": "Timing Oracle — Non-Constant-Time Secret Comparison on `index.js:81` could expose production credentials and API keys. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $24k · likely $138k · worst $778k. Dominant driver: legal counsel. Comparable: Generic finding — likely cost driven by user count + jurisdiction stack."
754
- }
755
- },
756
- {
757
- "id": "631940e0604686a0",
758
- "kind": "logic",
759
- "severity": "medium",
760
- "vuln": "Missing Timeout on Outbound HTTP Request (DoS)",
761
- "cwe": "CWE-400",
762
- "stride": "Denial of Service",
763
- "file": "index.js",
764
- "line": 83,
765
- "snippet": "const res = await fetch(url, {",
766
- "fix": {
767
- "description": "Set a timeout on all outbound requests to prevent event-loop starvation from stalled upstreams.",
768
- "code": "// fetch (Node 18+)\nconst resp = await fetch(url, { signal: AbortSignal.timeout(5000) });\n\n// axios\nawait axios.get(url, { timeout: 5000 });\n\n// node http\nconst req = http.get(url, cb);\nreq.setTimeout(5000, () => req.destroy());"
769
- },
770
- "blastRadius": {
771
- "scope": "all-users",
772
- "dataAtRisk": [
773
- "config"
774
- ],
775
- "userCount": 50,
776
- "industry": "generic",
777
- "jurisdictions": [],
778
- "controlsApplied": [],
779
- "dollarBest": 23250,
780
- "dollarLikely": 136250,
781
- "dollarWorst": 775000,
782
- "dollarLow": 23250,
783
- "dollarHigh": 775000,
784
- "components": {
785
- "incidentResponse": {
786
- "low": 8000,
787
- "likely": 50000,
788
- "high": 250000
789
- },
790
- "legal": {
791
- "low": 10000,
792
- "likely": 75000,
793
- "high": 500000
794
- },
795
- "crisisPR": {
796
- "low": 0,
797
- "likely": 0,
798
- "high": 0
799
- },
800
- "notification": {
801
- "low": 5000,
802
- "likely": 10000,
803
- "high": 15000
804
- },
805
- "creditMonitoring": {
806
- "low": 0,
807
- "likely": 0,
808
- "high": 0
809
- },
810
- "regulatoryFines": {
811
- "low": 0,
812
- "likely": 0,
813
- "high": 0
814
- },
815
- "directDamage": {
816
- "low": 250,
817
- "likely": 1250,
818
- "high": 10000
819
- },
820
- "classAction": {
821
- "low": 0,
822
- "likely": 0,
823
- "high": 0
824
- },
825
- "lostBusiness": {
826
- "low": 0,
827
- "likely": 0,
828
- "high": 0
829
- }
830
- },
831
- "dominantDriver": "legal counsel",
832
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
833
- "confidence": "low",
834
- "narrative": "Missing Timeout on Outbound HTTP Request (DoS) on `index.js:83` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
835
- }
836
- },
837
- {
838
- "id": "a59efade4197e6b8",
839
- "kind": "logic",
840
- "severity": "medium",
841
- "vuln": "Missing Timeout on Outbound HTTP Request (DoS)",
842
- "cwe": "CWE-400",
843
- "stride": "Denial of Service",
844
- "file": "index.js",
845
- "line": 192,
846
- "snippet": "const r = await fetch(url, {",
847
- "fix": {
848
- "description": "Set a timeout on all outbound requests to prevent event-loop starvation from stalled upstreams.",
849
- "code": "// fetch (Node 18+)\nconst resp = await fetch(url, { signal: AbortSignal.timeout(5000) });\n\n// axios\nawait axios.get(url, { timeout: 5000 });\n\n// node http\nconst req = http.get(url, cb);\nreq.setTimeout(5000, () => req.destroy());"
850
- },
851
- "blastRadius": {
852
- "scope": "all-users",
853
- "dataAtRisk": [
854
- "config"
855
- ],
856
- "userCount": 50,
857
- "industry": "generic",
858
- "jurisdictions": [],
859
- "controlsApplied": [],
860
- "dollarBest": 23250,
861
- "dollarLikely": 136250,
862
- "dollarWorst": 775000,
863
- "dollarLow": 23250,
864
- "dollarHigh": 775000,
865
- "components": {
866
- "incidentResponse": {
867
- "low": 8000,
868
- "likely": 50000,
869
- "high": 250000
870
- },
871
- "legal": {
872
- "low": 10000,
873
- "likely": 75000,
874
- "high": 500000
875
- },
876
- "crisisPR": {
877
- "low": 0,
878
- "likely": 0,
879
- "high": 0
880
- },
881
- "notification": {
882
- "low": 5000,
883
- "likely": 10000,
884
- "high": 15000
885
- },
886
- "creditMonitoring": {
887
- "low": 0,
888
- "likely": 0,
889
- "high": 0
890
- },
891
- "regulatoryFines": {
892
- "low": 0,
893
- "likely": 0,
894
- "high": 0
895
- },
896
- "directDamage": {
897
- "low": 250,
898
- "likely": 1250,
899
- "high": 10000
900
- },
901
- "classAction": {
902
- "low": 0,
903
- "likely": 0,
904
- "high": 0
905
- },
906
- "lostBusiness": {
907
- "low": 0,
908
- "likely": 0,
909
- "high": 0
910
- }
911
- },
912
- "dominantDriver": "legal counsel",
913
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
914
- "confidence": "low",
915
- "narrative": "Missing Timeout on Outbound HTTP Request (DoS) on `index.js:192` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
916
- }
917
- },
918
- {
919
- "id": "70f13848a5590cd0",
920
- "kind": "logic",
921
- "severity": "medium",
922
- "vuln": "Missing Timeout on Outbound HTTP Request (DoS)",
923
- "cwe": "CWE-400",
924
- "stride": "Denial of Service",
925
- "file": "index.js",
926
- "line": 237,
927
- "snippet": "const r = await fetch('https://events.pagerduty.com/v2/enqueue', {",
928
- "fix": {
929
- "description": "Set a timeout on all outbound requests to prevent event-loop starvation from stalled upstreams.",
930
- "code": "// fetch (Node 18+)\nconst resp = await fetch(url, { signal: AbortSignal.timeout(5000) });\n\n// axios\nawait axios.get(url, { timeout: 5000 });\n\n// node http\nconst req = http.get(url, cb);\nreq.setTimeout(5000, () => req.destroy());"
931
- },
932
- "blastRadius": {
933
- "scope": "all-users",
934
- "dataAtRisk": [
935
- "config"
936
- ],
937
- "userCount": 50,
938
- "industry": "generic",
939
- "jurisdictions": [],
940
- "controlsApplied": [],
941
- "dollarBest": 23250,
942
- "dollarLikely": 136250,
943
- "dollarWorst": 775000,
944
- "dollarLow": 23250,
945
- "dollarHigh": 775000,
946
- "components": {
947
- "incidentResponse": {
948
- "low": 8000,
949
- "likely": 50000,
950
- "high": 250000
951
- },
952
- "legal": {
953
- "low": 10000,
954
- "likely": 75000,
955
- "high": 500000
956
- },
957
- "crisisPR": {
958
- "low": 0,
959
- "likely": 0,
960
- "high": 0
961
- },
962
- "notification": {
963
- "low": 5000,
964
- "likely": 10000,
965
- "high": 15000
966
- },
967
- "creditMonitoring": {
968
- "low": 0,
969
- "likely": 0,
970
- "high": 0
971
- },
972
- "regulatoryFines": {
973
- "low": 0,
974
- "likely": 0,
975
- "high": 0
976
- },
977
- "directDamage": {
978
- "low": 250,
979
- "likely": 1250,
980
- "high": 10000
981
- },
982
- "classAction": {
983
- "low": 0,
984
- "likely": 0,
985
- "high": 0
986
- },
987
- "lostBusiness": {
988
- "low": 0,
989
- "likely": 0,
990
- "high": 0
991
- }
992
- },
993
- "dominantDriver": "legal counsel",
994
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
995
- "confidence": "low",
996
- "narrative": "Missing Timeout on Outbound HTTP Request (DoS) on `index.js:237` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
997
- }
998
- },
999
- {
1000
- "id": "76866788c737e89b",
1001
- "kind": "logic",
1002
- "severity": "medium",
1003
- "vuln": "Missing Timeout on Outbound HTTP Request (DoS)",
1004
- "cwe": "CWE-400",
1005
- "stride": "Denial of Service",
1006
- "file": "index.js",
1007
- "line": 291,
1008
- "snippet": "const r = await fetch(url, {",
1009
- "fix": {
1010
- "description": "Set a timeout on all outbound requests to prevent event-loop starvation from stalled upstreams.",
1011
- "code": "// fetch (Node 18+)\nconst resp = await fetch(url, { signal: AbortSignal.timeout(5000) });\n\n// axios\nawait axios.get(url, { timeout: 5000 });\n\n// node http\nconst req = http.get(url, cb);\nreq.setTimeout(5000, () => req.destroy());"
1012
- },
1013
- "blastRadius": {
1014
- "scope": "all-users",
1015
- "dataAtRisk": [
1016
- "config"
1017
- ],
1018
- "userCount": 50,
1019
- "industry": "generic",
1020
- "jurisdictions": [],
1021
- "controlsApplied": [],
1022
- "dollarBest": 23250,
1023
- "dollarLikely": 136250,
1024
- "dollarWorst": 775000,
1025
- "dollarLow": 23250,
1026
- "dollarHigh": 775000,
1027
- "components": {
1028
- "incidentResponse": {
1029
- "low": 8000,
1030
- "likely": 50000,
1031
- "high": 250000
1032
- },
1033
- "legal": {
1034
- "low": 10000,
1035
- "likely": 75000,
1036
- "high": 500000
1037
- },
1038
- "crisisPR": {
1039
- "low": 0,
1040
- "likely": 0,
1041
- "high": 0
1042
- },
1043
- "notification": {
1044
- "low": 5000,
1045
- "likely": 10000,
1046
- "high": 15000
1047
- },
1048
- "creditMonitoring": {
1049
- "low": 0,
1050
- "likely": 0,
1051
- "high": 0
1052
- },
1053
- "regulatoryFines": {
1054
- "low": 0,
1055
- "likely": 0,
1056
- "high": 0
1057
- },
1058
- "directDamage": {
1059
- "low": 250,
1060
- "likely": 1250,
1061
- "high": 10000
1062
- },
1063
- "classAction": {
1064
- "low": 0,
1065
- "likely": 0,
1066
- "high": 0
1067
- },
1068
- "lostBusiness": {
1069
- "low": 0,
1070
- "likely": 0,
1071
- "high": 0
1072
- }
1073
- },
1074
- "dominantDriver": "legal counsel",
1075
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
1076
- "confidence": "low",
1077
- "narrative": "Missing Timeout on Outbound HTTP Request (DoS) on `index.js:291` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
1078
- }
1079
- },
1080
- {
1081
- "id": "logic:index.js:23:TOCTOU:_existsSync_followed_by_file_op",
1082
- "kind": "logic",
1083
- "severity": "medium",
1084
- "vuln": "TOCTOU: existsSync followed by file op",
1085
- "cwe": "CWE-367",
1086
- "stride": "Tampering",
1087
- "file": "index.js",
1088
- "line": 23,
1089
- "snippet": "if (!fs.existsSync(fp)) return {};",
1090
- "fix": {
1091
- "description": "Replace the check-then-act sequence with a single atomic operation (e.g., `fs.open` with appropriate flags). Between `existsSync` and the file op the file can be replaced by a symlink or removed.",
1092
- "code": ""
1093
- },
1094
- "blastRadius": {
1095
- "scope": "all-users",
1096
- "dataAtRisk": [
1097
- "config"
1098
- ],
1099
- "userCount": 50,
1100
- "industry": "generic",
1101
- "jurisdictions": [],
1102
- "controlsApplied": [],
1103
- "dollarBest": 23250,
1104
- "dollarLikely": 136250,
1105
- "dollarWorst": 775000,
1106
- "dollarLow": 23250,
1107
- "dollarHigh": 775000,
1108
- "components": {
1109
- "incidentResponse": {
1110
- "low": 8000,
1111
- "likely": 50000,
1112
- "high": 250000
1113
- },
1114
- "legal": {
1115
- "low": 10000,
1116
- "likely": 75000,
1117
- "high": 500000
1118
- },
1119
- "crisisPR": {
1120
- "low": 0,
1121
- "likely": 0,
1122
- "high": 0
1123
- },
1124
- "notification": {
1125
- "low": 5000,
1126
- "likely": 10000,
1127
- "high": 15000
1128
- },
1129
- "creditMonitoring": {
1130
- "low": 0,
1131
- "likely": 0,
1132
- "high": 0
1133
- },
1134
- "regulatoryFines": {
1135
- "low": 0,
1136
- "likely": 0,
1137
- "high": 0
1138
- },
1139
- "directDamage": {
1140
- "low": 250,
1141
- "likely": 1250,
1142
- "high": 10000
1143
- },
1144
- "classAction": {
1145
- "low": 0,
1146
- "likely": 0,
1147
- "high": 0
1148
- },
1149
- "lostBusiness": {
1150
- "low": 0,
1151
- "likely": 0,
1152
- "high": 0
1153
- }
1154
- },
1155
- "dominantDriver": "legal counsel",
1156
- "comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
1157
- "confidence": "low",
1158
- "narrative": "TOCTOU: existsSync followed by file op on `index.js:23` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Generic finding — likely cost driven by user count + jurisdiction stack."
1159
- }
1160
- },
1161
- {
1162
- "id": "a4b3b5acbb4ac145",
1163
- "kind": "logic",
1164
- "severity": "medium",
1165
- "vuln": "Missing Timeout on Outbound HTTP Request (DoS)",
1166
- "cwe": "CWE-400",
1167
- "stride": "Denial of Service",
1168
- "file": "tickets.js",
1169
- "line": 76,
1170
- "snippet": "const res = await fetch('https://api.linear.app/graphql', {",
1171
- "fix": {
1172
- "description": "Set a timeout on all outbound requests to prevent event-loop starvation from stalled upstreams.",
1173
- "code": "// fetch (Node 18+)\nconst resp = await fetch(url, { signal: AbortSignal.timeout(5000) });\n\n// axios\nawait axios.get(url, { timeout: 5000 });\n\n// node http\nconst req = http.get(url, cb);\nreq.setTimeout(5000, () => req.destroy());"
1174
- },
1175
- "blastRadius": {
1176
- "scope": "all-users",
1177
- "dataAtRisk": [
1178
- "config"
1179
- ],
1180
- "userCount": 50,
1181
- "industry": "generic",
1182
- "jurisdictions": [],
1183
- "controlsApplied": [],
1184
- "dollarBest": 23250,
1185
- "dollarLikely": 136250,
1186
- "dollarWorst": 775000,
1187
- "dollarLow": 23250,
1188
- "dollarHigh": 775000,
1189
- "components": {
1190
- "incidentResponse": {
1191
- "low": 8000,
1192
- "likely": 50000,
1193
- "high": 250000
1194
- },
1195
- "legal": {
1196
- "low": 10000,
1197
- "likely": 75000,
1198
- "high": 500000
1199
- },
1200
- "crisisPR": {
1201
- "low": 0,
1202
- "likely": 0,
1203
- "high": 0
1204
- },
1205
- "notification": {
1206
- "low": 5000,
1207
- "likely": 10000,
1208
- "high": 15000
1209
- },
1210
- "creditMonitoring": {
1211
- "low": 0,
1212
- "likely": 0,
1213
- "high": 0
1214
- },
1215
- "regulatoryFines": {
1216
- "low": 0,
1217
- "likely": 0,
1218
- "high": 0
1219
- },
1220
- "directDamage": {
1221
- "low": 250,
1222
- "likely": 1250,
1223
- "high": 10000
1224
- },
1225
- "classAction": {
1226
- "low": 0,
1227
- "likely": 0,
1228
- "high": 0
1229
- },
1230
- "lostBusiness": {
1231
- "low": 0,
1232
- "likely": 0,
1233
- "high": 0
1234
- }
1235
- },
1236
- "dominantDriver": "legal counsel",
1237
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
1238
- "confidence": "low",
1239
- "narrative": "Missing Timeout on Outbound HTTP Request (DoS) on `tickets.js:76` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
1240
- }
1241
- },
1242
- {
1243
- "id": "e2b4be44e7646253",
1244
- "kind": "logic",
1245
- "severity": "medium",
1246
- "vuln": "Missing Timeout on Outbound HTTP Request (DoS)",
1247
- "cwe": "CWE-400",
1248
- "stride": "Denial of Service",
1249
- "file": "tickets.js",
1250
- "line": 112,
1251
- "snippet": "const res = await fetch(`${base.replace(/\\/$/, '')}${urlPath}`, {",
1252
- "fix": {
1253
- "description": "Set a timeout on all outbound requests to prevent event-loop starvation from stalled upstreams.",
1254
- "code": "// fetch (Node 18+)\nconst resp = await fetch(url, { signal: AbortSignal.timeout(5000) });\n\n// axios\nawait axios.get(url, { timeout: 5000 });\n\n// node http\nconst req = http.get(url, cb);\nreq.setTimeout(5000, () => req.destroy());"
1255
- },
1256
- "blastRadius": {
1257
- "scope": "all-users",
1258
- "dataAtRisk": [
1259
- "config"
1260
- ],
1261
- "userCount": 50,
1262
- "industry": "generic",
1263
- "jurisdictions": [],
1264
- "controlsApplied": [],
1265
- "dollarBest": 23250,
1266
- "dollarLikely": 136250,
1267
- "dollarWorst": 775000,
1268
- "dollarLow": 23250,
1269
- "dollarHigh": 775000,
1270
- "components": {
1271
- "incidentResponse": {
1272
- "low": 8000,
1273
- "likely": 50000,
1274
- "high": 250000
1275
- },
1276
- "legal": {
1277
- "low": 10000,
1278
- "likely": 75000,
1279
- "high": 500000
1280
- },
1281
- "crisisPR": {
1282
- "low": 0,
1283
- "likely": 0,
1284
- "high": 0
1285
- },
1286
- "notification": {
1287
- "low": 5000,
1288
- "likely": 10000,
1289
- "high": 15000
1290
- },
1291
- "creditMonitoring": {
1292
- "low": 0,
1293
- "likely": 0,
1294
- "high": 0
1295
- },
1296
- "regulatoryFines": {
1297
- "low": 0,
1298
- "likely": 0,
1299
- "high": 0
1300
- },
1301
- "directDamage": {
1302
- "low": 250,
1303
- "likely": 1250,
1304
- "high": 10000
1305
- },
1306
- "classAction": {
1307
- "low": 0,
1308
- "likely": 0,
1309
- "high": 0
1310
- },
1311
- "lostBusiness": {
1312
- "low": 0,
1313
- "likely": 0,
1314
- "high": 0
1315
- }
1316
- },
1317
- "dominantDriver": "legal counsel",
1318
- "comparable": "Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage",
1319
- "confidence": "low",
1320
- "narrative": "Missing Timeout on Outbound HTTP Request (DoS) on `tickets.js:112` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Air Canada 2024 LLM chatbot DoS → court-ordered refunds + reputational damage."
1321
- }
1322
- },
1323
- {
1324
- "id": "logic:tickets.js:26:TOCTOU:_existsSync_followed_by_file_op",
1325
- "kind": "logic",
1326
- "severity": "medium",
1327
- "vuln": "TOCTOU: existsSync followed by file op",
1328
- "cwe": "CWE-367",
1329
- "stride": "Tampering",
1330
- "file": "tickets.js",
1331
- "line": 26,
1332
- "snippet": "if (!fs.existsSync(fp)) return {};",
1333
- "fix": {
1334
- "description": "Replace the check-then-act sequence with a single atomic operation (e.g., `fs.open` with appropriate flags). Between `existsSync` and the file op the file can be replaced by a symlink or removed.",
1335
- "code": ""
1336
- },
1337
- "blastRadius": {
1338
- "scope": "all-users",
1339
- "dataAtRisk": [
1340
- "config"
1341
- ],
1342
- "userCount": 50,
1343
- "industry": "generic",
1344
- "jurisdictions": [],
1345
- "controlsApplied": [],
1346
- "dollarBest": 23250,
1347
- "dollarLikely": 136250,
1348
- "dollarWorst": 775000,
1349
- "dollarLow": 23250,
1350
- "dollarHigh": 775000,
1351
- "components": {
1352
- "incidentResponse": {
1353
- "low": 8000,
1354
- "likely": 50000,
1355
- "high": 250000
1356
- },
1357
- "legal": {
1358
- "low": 10000,
1359
- "likely": 75000,
1360
- "high": 500000
1361
- },
1362
- "crisisPR": {
1363
- "low": 0,
1364
- "likely": 0,
1365
- "high": 0
1366
- },
1367
- "notification": {
1368
- "low": 5000,
1369
- "likely": 10000,
1370
- "high": 15000
1371
- },
1372
- "creditMonitoring": {
1373
- "low": 0,
1374
- "likely": 0,
1375
- "high": 0
1376
- },
1377
- "regulatoryFines": {
1378
- "low": 0,
1379
- "likely": 0,
1380
- "high": 0
1381
- },
1382
- "directDamage": {
1383
- "low": 250,
1384
- "likely": 1250,
1385
- "high": 10000
1386
- },
1387
- "classAction": {
1388
- "low": 0,
1389
- "likely": 0,
1390
- "high": 0
1391
- },
1392
- "lostBusiness": {
1393
- "low": 0,
1394
- "likely": 0,
1395
- "high": 0
1396
- }
1397
- },
1398
- "dominantDriver": "legal counsel",
1399
- "comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
1400
- "confidence": "low",
1401
- "narrative": "TOCTOU: existsSync followed by file op on `tickets.js:26` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Generic finding — likely cost driven by user count + jurisdiction stack."
1402
- }
1403
- },
1404
- {
1405
- "id": "logic:tickets.js:146:TOCTOU:_existsSync_followed_by_file_op",
1406
- "kind": "logic",
1407
- "severity": "medium",
1408
- "vuln": "TOCTOU: existsSync followed by file op",
1409
- "cwe": "CWE-367",
1410
- "stride": "Tampering",
1411
- "file": "tickets.js",
1412
- "line": 146,
1413
- "snippet": "if (!fs.existsSync(lastScanPath)) return { ok: false, error: 'no last-scan.json — run a scan first' };",
1414
- "fix": {
1415
- "description": "Replace the check-then-act sequence with a single atomic operation (e.g., `fs.open` with appropriate flags). Between `existsSync` and the file op the file can be replaced by a symlink or removed.",
1416
- "code": ""
1417
- },
1418
- "blastRadius": {
1419
- "scope": "all-users",
1420
- "dataAtRisk": [
1421
- "config"
1422
- ],
1423
- "userCount": 50,
1424
- "industry": "generic",
1425
- "jurisdictions": [],
1426
- "controlsApplied": [],
1427
- "dollarBest": 23250,
1428
- "dollarLikely": 136250,
1429
- "dollarWorst": 775000,
1430
- "dollarLow": 23250,
1431
- "dollarHigh": 775000,
1432
- "components": {
1433
- "incidentResponse": {
1434
- "low": 8000,
1435
- "likely": 50000,
1436
- "high": 250000
1437
- },
1438
- "legal": {
1439
- "low": 10000,
1440
- "likely": 75000,
1441
- "high": 500000
1442
- },
1443
- "crisisPR": {
1444
- "low": 0,
1445
- "likely": 0,
1446
- "high": 0
1447
- },
1448
- "notification": {
1449
- "low": 5000,
1450
- "likely": 10000,
1451
- "high": 15000
1452
- },
1453
- "creditMonitoring": {
1454
- "low": 0,
1455
- "likely": 0,
1456
- "high": 0
1457
- },
1458
- "regulatoryFines": {
1459
- "low": 0,
1460
- "likely": 0,
1461
- "high": 0
1462
- },
1463
- "directDamage": {
1464
- "low": 250,
1465
- "likely": 1250,
1466
- "high": 10000
1467
- },
1468
- "classAction": {
1469
- "low": 0,
1470
- "likely": 0,
1471
- "high": 0
1472
- },
1473
- "lostBusiness": {
1474
- "low": 0,
1475
- "likely": 0,
1476
- "high": 0
1477
- }
1478
- },
1479
- "dominantDriver": "legal counsel",
1480
- "comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
1481
- "confidence": "low",
1482
- "narrative": "TOCTOU: existsSync followed by file op on `tickets.js:146` could expose configuration / internal data. Context: general SaaS / no specific regulatory exposure. Estimated cost: best $23k · likely $136k · worst $775k. Dominant driver: legal counsel. Comparable: Generic finding — likely cost driven by user count + jurisdiction stack."
1483
- }
1484
- }
1485
- ],
1486
- "bundles": [],
1487
- "routes": [],
1488
- "components": [],
1489
- "suppressedCount": 0,
1490
- "blastRadiusSignals": {
1491
- "industry": "generic",
1492
- "industryConfidence": "low",
1493
- "jurisdictions": [],
1494
- "controls": [],
1495
- "estimatedUsers": 50,
1496
- "revenueIndicator": "pre-revenue",
1497
- "hasStripe": false,
1498
- "hasAuth": false,
1499
- "hasUserTable": false,
1500
- "hasPII": false,
1501
- "hasPHI": false,
1502
- "hasS3": false
1503
- }
1504
- }