@clear-capabilities/agentic-security-scanner 0.74.1 → 0.76.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.
- package/CHANGELOG.md +88 -0
- package/bin/.agentic-security/findings.json +30 -11
- package/bin/.agentic-security/last-scan.json +30 -11
- package/bin/.agentic-security/last-scan.json.sig +1 -1
- package/bin/.agentic-security/scan-history.json +32 -22
- package/bin/.agentic-security/streak.json +5 -5
- package/bin/agentic-security.js +2 -2
- package/dist/838.index.js +152 -0
- package/dist/985.index.js +1769 -0
- package/dist/agentic-security.mjs +1 -1
- package/dist/agentic-security.mjs.sha256 +1 -1
- package/package.json +2 -2
- package/src/mcp/.agentic-security/findings.json +133 -88
- package/src/mcp/.agentic-security/last-scan.json +133 -88
- package/src/mcp/.agentic-security/last-scan.json.sig +1 -1
- package/src/mcp/.agentic-security/scan-history.json +138 -81
- package/src/mcp/.agentic-security/streak.json +4 -4
- package/src/mcp/tools.js +17 -2
- package/src/sca/.agentic-security/findings.json +1096 -0
- package/src/sca/.agentic-security/last-scan.json +1096 -0
- package/src/sca/.agentic-security/last-scan.json.sig +1 -0
- package/src/sca/.agentic-security/scan-history.json +18 -0
- package/src/sca/.agentic-security/streak.json +21 -0
- package/src/sca/base-images.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.76.0 — Command consolidation: 80 → 38 slash commands
|
|
4
|
+
|
|
5
|
+
Simplified the command surface from 80 individual slash commands down to
|
|
6
|
+
38 by merging related commands into consolidated routers with flags.
|
|
7
|
+
No functionality removed — all logic preserved behind flags on fewer,
|
|
8
|
+
more discoverable parent commands.
|
|
9
|
+
|
|
10
|
+
### New consolidated commands
|
|
11
|
+
|
|
12
|
+
| New command | Absorbed | Routing |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `/audit` | db-audit, auth-audit, rate-limit-check, webhook-audit, env-check, csp-cors, deploy-check, launch-check, llm-cost-ceiling, prompt-firewall | `--target <area>` or `--all` |
|
|
15
|
+
| `/threat` | threat-model, personas, playbook, bounty, adversary, attack-surface, trust-boundary, spof | `--view <name>` |
|
|
16
|
+
| `/llm` | llm-redteam, jailbreak-detector, llm-eval | `--mode redteam\|jailbreak\|eval` |
|
|
17
|
+
| `/ci` | ci-gate, predeploy-gate, install-hooks | default / `--predeploy` / `--hooks` |
|
|
18
|
+
| `/generate` | privacy-docs, disaster-playbook, social-media, security-tests | `--type privacy\|disaster\|social\|tests` |
|
|
19
|
+
| `/scanner` | self-test, diff-scan, scan-baseline, concurrency-bugs, spec-drift | `--self-test` / `--diff` / `--baseline` / `--concurrency` / `--spec-drift` |
|
|
20
|
+
|
|
21
|
+
### Commands absorbed into existing commands
|
|
22
|
+
|
|
23
|
+
- `/why-fired` → `/explain --provenance --finding <id>`
|
|
24
|
+
- `/why-not` → `/explain --gap <CWE>`
|
|
25
|
+
- `/install-script-audit` → `/supply-chain-check --show install-scripts`
|
|
26
|
+
- `/vendor-audit` → `/supply-chain-check --show vendored`
|
|
27
|
+
|
|
28
|
+
### Deleted deprecated aliases (11)
|
|
29
|
+
|
|
30
|
+
ci-gate-multi, rotate-key-auto, trim-dead-code, trim-dependencies,
|
|
31
|
+
story-explain, security-badge, security-onepager, trust-page,
|
|
32
|
+
dep-pinning, dep-freshness, dep-alternatives.
|
|
33
|
+
|
|
34
|
+
## 0.75.1 — /agent-harness-assessment + interactive compliance routing + README badge relocation
|
|
35
|
+
|
|
36
|
+
Three follow-ups to the 0.75.0 surface:
|
|
37
|
+
|
|
38
|
+
**Renamed `/executive-summary` → `/agent-harness-assessment`.** The
|
|
39
|
+
previous name framed this as a finance-style report. The actual artifact
|
|
40
|
+
is an assessment of the AI-agent harness: a CISO/buyer reading it wants
|
|
41
|
+
to know whether to trust an AI agent working in this project, not just
|
|
42
|
+
see a posture grade. The new name reflects the audience.
|
|
43
|
+
|
|
44
|
+
**Interactive compliance step.** After printing the six-control
|
|
45
|
+
assessment, the command now asks (via AskUserQuestion) which compliance
|
|
46
|
+
frameworks the reader wants generated NOW — NIST AI 600-1, OWASP ASVS,
|
|
47
|
+
OWASP LLM Top 10 (2025), or none. For each selection, the model invokes
|
|
48
|
+
`/compliance-report <fw>` with the matching positional argument
|
|
49
|
+
(`nist`, `asvs`, `llm`) so an auditor-ready file lands on disk. The
|
|
50
|
+
Compliance section in the assessment now says what evidence COULD be
|
|
51
|
+
produced; the interactive step closes the loop to evidence that EXISTS.
|
|
52
|
+
|
|
53
|
+
**README "Status badge" section relocated** from the top-of-README hero
|
|
54
|
+
region into the Security Pros section, between the 5-minute pro setup
|
|
55
|
+
and the full pro catalog. Adopting the badge is a pro-shaped step
|
|
56
|
+
(it requires CI wiring + a baseline scan). Three example badges now
|
|
57
|
+
render on three distinct lines via trailing `<br>` so the severity
|
|
58
|
+
ladder is legible at a glance.
|
|
59
|
+
|
|
60
|
+
## 0.75.0 — /executive-summary: CISO-facing six-control posture report
|
|
61
|
+
|
|
62
|
+
New top-level command for buyer-questionnaire / diligence / CISO use.
|
|
63
|
+
`/executive-summary` prints a plain-English briefing of the six harness
|
|
64
|
+
controls (Tool access, Guardrails, Feedback loops, Audit evidence,
|
|
65
|
+
Failure mode, Compliance) with live status indicators drawn from the
|
|
66
|
+
current project state — hook activation, scan-signature presence,
|
|
67
|
+
audit-log entry count, remote-witness configuration, compliance artifacts.
|
|
68
|
+
|
|
69
|
+
Each control renders four named subsections modeled on `/explain`:
|
|
70
|
+
**What it does** (2-3 paragraphs of plain English), **Specifically**
|
|
71
|
+
(the concrete enumerated list of allows/blocks/intercepts), **What would
|
|
72
|
+
have to go wrong for this to fail** (threat model in one paragraph), and
|
|
73
|
+
**Live status (this project)** (verifiable indicators). The "Specifically"
|
|
74
|
+
block names actual reserved paths, every shell command intercepted, every
|
|
75
|
+
code-edit pattern blocked, every audit-log property, every refusal point,
|
|
76
|
+
and every compliance artifact format — so a reviewer can verify the claim
|
|
77
|
+
without opening any source file.
|
|
78
|
+
|
|
79
|
+
Flags: `--format md` for markdown output; `--output PATH` writes to disk
|
|
80
|
+
(typically `EXECUTIVE_SUMMARY.md` for buyer questionnaires).
|
|
81
|
+
|
|
82
|
+
## 0.74.2 — npm package + version alignment
|
|
83
|
+
|
|
84
|
+
First release published to npm under the org that owns the scope:
|
|
85
|
+
`@clear-capabilities/agentic-security-scanner`. Adds a bin alias
|
|
86
|
+
`agentic-security-scanner` (→ same dist bundle) so the documented
|
|
87
|
+
`npx @clear-capabilities/agentic-security-scanner secure .` resolves
|
|
88
|
+
an executable. Aligns the source-tree version with the npm registry
|
|
89
|
+
after the 0.74.1 metadata-only publish.
|
|
90
|
+
|
|
3
91
|
## 0.74.0 — viral surface: PoC video gen + security-tutor skill + personality voices + compare runner
|
|
4
92
|
|
|
5
93
|
Four shareability lifts.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"scanId": "
|
|
3
|
-
"startedAt": "2026-05-
|
|
4
|
-
"durationMs":
|
|
2
|
+
"scanId": "d01219ed-b5bf-4fde-bf3c-4f31c0ceaa41",
|
|
3
|
+
"startedAt": "2026-05-21T16:13:40.849Z",
|
|
4
|
+
"durationMs": 281,
|
|
5
5
|
"scanned": {
|
|
6
6
|
"files": 7,
|
|
7
7
|
"lines": 0
|
|
@@ -86,7 +86,9 @@
|
|
|
86
86
|
"comparable": "Snyk 2022 path-traversal disclosure → CDN cache poisoning + .env exfil",
|
|
87
87
|
"confidence": "low",
|
|
88
88
|
"narrative": "Sensitive Directory Path Construction on `agentic-security-audit.js:51` 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: Snyk 2022 path-traversal disclosure → CDN cache poisoning + .env exfil."
|
|
89
|
-
}
|
|
89
|
+
},
|
|
90
|
+
"parser": "LOGIC",
|
|
91
|
+
"family": null
|
|
90
92
|
},
|
|
91
93
|
{
|
|
92
94
|
"id": "toctou-fs:agentic-security-audit.js:55",
|
|
@@ -195,6 +197,7 @@
|
|
|
195
197
|
"unvalidated": true,
|
|
196
198
|
"cross_language": false,
|
|
197
199
|
"family": "toctou-file-existence-permission-check-b",
|
|
200
|
+
"parser": "TOCTOU",
|
|
198
201
|
"_unsigned": false,
|
|
199
202
|
"_passThroughSigning": false,
|
|
200
203
|
"signatureStatus": "verified",
|
|
@@ -418,6 +421,7 @@
|
|
|
418
421
|
"unvalidated": true,
|
|
419
422
|
"cross_language": false,
|
|
420
423
|
"family": "toctou-file-existence-permission-check-b",
|
|
424
|
+
"parser": "TOCTOU",
|
|
421
425
|
"_unsigned": false,
|
|
422
426
|
"_passThroughSigning": false,
|
|
423
427
|
"signatureStatus": "verified",
|
|
@@ -639,6 +643,7 @@
|
|
|
639
643
|
"unvalidated": true,
|
|
640
644
|
"cross_language": false,
|
|
641
645
|
"family": "toctou-file-existence-permission-check-b",
|
|
646
|
+
"parser": "TOCTOU",
|
|
642
647
|
"_unsigned": false,
|
|
643
648
|
"_passThroughSigning": false,
|
|
644
649
|
"signatureStatus": "verified",
|
|
@@ -860,6 +865,7 @@
|
|
|
860
865
|
"unvalidated": true,
|
|
861
866
|
"cross_language": false,
|
|
862
867
|
"family": "toctou-file-existence-permission-check-b",
|
|
868
|
+
"parser": "TOCTOU",
|
|
863
869
|
"_unsigned": false,
|
|
864
870
|
"_passThroughSigning": false,
|
|
865
871
|
"signatureStatus": "verified",
|
|
@@ -1053,7 +1059,9 @@
|
|
|
1053
1059
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1054
1060
|
"confidence": "low",
|
|
1055
1061
|
"narrative": "Missing Unsigned Numeric Validation on `agentic-security-audit.js:131` 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."
|
|
1056
|
-
}
|
|
1062
|
+
},
|
|
1063
|
+
"parser": "LOGIC",
|
|
1064
|
+
"family": null
|
|
1057
1065
|
},
|
|
1058
1066
|
{
|
|
1059
1067
|
"id": "logic:agentic-security-audit.js:55:TOCTOU:_existsSync_followed_by_file_op",
|
|
@@ -1134,7 +1142,9 @@
|
|
|
1134
1142
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1135
1143
|
"confidence": "low",
|
|
1136
1144
|
"narrative": "TOCTOU: existsSync followed by file op on `agentic-security-audit.js:55` 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."
|
|
1137
|
-
}
|
|
1145
|
+
},
|
|
1146
|
+
"parser": "LOGIC",
|
|
1147
|
+
"family": null
|
|
1138
1148
|
},
|
|
1139
1149
|
{
|
|
1140
1150
|
"id": "e2445e40b5e43c01",
|
|
@@ -1215,7 +1225,9 @@
|
|
|
1215
1225
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1216
1226
|
"confidence": "low",
|
|
1217
1227
|
"narrative": "Race Condition (TOCTOU) on `agentic-security-consistency.js:66` 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."
|
|
1218
|
-
}
|
|
1228
|
+
},
|
|
1229
|
+
"parser": "LOGIC",
|
|
1230
|
+
"family": null
|
|
1219
1231
|
},
|
|
1220
1232
|
{
|
|
1221
1233
|
"id": "logic:agentic-security-consistency.js:44:TOCTOU:_existsSync_followed_by_file_op",
|
|
@@ -1296,7 +1308,9 @@
|
|
|
1296
1308
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1297
1309
|
"confidence": "low",
|
|
1298
1310
|
"narrative": "TOCTOU: existsSync followed by file op on `agentic-security-consistency.js:44` 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."
|
|
1299
|
-
}
|
|
1311
|
+
},
|
|
1312
|
+
"parser": "LOGIC",
|
|
1313
|
+
"family": null
|
|
1300
1314
|
},
|
|
1301
1315
|
{
|
|
1302
1316
|
"id": "logic:agentic-security-consistency.js:66:TOCTOU:_existsSync_followed_by_file_op",
|
|
@@ -1377,7 +1391,9 @@
|
|
|
1377
1391
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1378
1392
|
"confidence": "low",
|
|
1379
1393
|
"narrative": "TOCTOU: existsSync followed by file op on `agentic-security-consistency.js:66` 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."
|
|
1380
|
-
}
|
|
1394
|
+
},
|
|
1395
|
+
"parser": "LOGIC",
|
|
1396
|
+
"family": null
|
|
1381
1397
|
},
|
|
1382
1398
|
{
|
|
1383
1399
|
"id": "49e1e00962a1950c",
|
|
@@ -1458,7 +1474,9 @@
|
|
|
1458
1474
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1459
1475
|
"confidence": "low",
|
|
1460
1476
|
"narrative": "Weak Randomness on `agentic-security-rule.js:98` 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."
|
|
1461
|
-
}
|
|
1477
|
+
},
|
|
1478
|
+
"parser": "LOGIC",
|
|
1479
|
+
"family": null
|
|
1462
1480
|
}
|
|
1463
1481
|
],
|
|
1464
1482
|
"bundles": [],
|
|
@@ -1573,5 +1591,6 @@
|
|
|
1573
1591
|
"alarms": [],
|
|
1574
1592
|
"note": "no-feedback-data"
|
|
1575
1593
|
}
|
|
1576
|
-
}
|
|
1594
|
+
},
|
|
1595
|
+
"annotatorErrors": []
|
|
1577
1596
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"scanId": "
|
|
3
|
-
"startedAt": "2026-05-
|
|
4
|
-
"durationMs":
|
|
2
|
+
"scanId": "d01219ed-b5bf-4fde-bf3c-4f31c0ceaa41",
|
|
3
|
+
"startedAt": "2026-05-21T16:13:40.849Z",
|
|
4
|
+
"durationMs": 281,
|
|
5
5
|
"scanned": {
|
|
6
6
|
"files": 7,
|
|
7
7
|
"lines": 0
|
|
@@ -86,7 +86,9 @@
|
|
|
86
86
|
"comparable": "Snyk 2022 path-traversal disclosure → CDN cache poisoning + .env exfil",
|
|
87
87
|
"confidence": "low",
|
|
88
88
|
"narrative": "Sensitive Directory Path Construction on `agentic-security-audit.js:51` 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: Snyk 2022 path-traversal disclosure → CDN cache poisoning + .env exfil."
|
|
89
|
-
}
|
|
89
|
+
},
|
|
90
|
+
"parser": "LOGIC",
|
|
91
|
+
"family": null
|
|
90
92
|
},
|
|
91
93
|
{
|
|
92
94
|
"id": "toctou-fs:agentic-security-audit.js:55",
|
|
@@ -195,6 +197,7 @@
|
|
|
195
197
|
"unvalidated": true,
|
|
196
198
|
"cross_language": false,
|
|
197
199
|
"family": "toctou-file-existence-permission-check-b",
|
|
200
|
+
"parser": "TOCTOU",
|
|
198
201
|
"_unsigned": false,
|
|
199
202
|
"_passThroughSigning": false,
|
|
200
203
|
"signatureStatus": "verified",
|
|
@@ -418,6 +421,7 @@
|
|
|
418
421
|
"unvalidated": true,
|
|
419
422
|
"cross_language": false,
|
|
420
423
|
"family": "toctou-file-existence-permission-check-b",
|
|
424
|
+
"parser": "TOCTOU",
|
|
421
425
|
"_unsigned": false,
|
|
422
426
|
"_passThroughSigning": false,
|
|
423
427
|
"signatureStatus": "verified",
|
|
@@ -639,6 +643,7 @@
|
|
|
639
643
|
"unvalidated": true,
|
|
640
644
|
"cross_language": false,
|
|
641
645
|
"family": "toctou-file-existence-permission-check-b",
|
|
646
|
+
"parser": "TOCTOU",
|
|
642
647
|
"_unsigned": false,
|
|
643
648
|
"_passThroughSigning": false,
|
|
644
649
|
"signatureStatus": "verified",
|
|
@@ -860,6 +865,7 @@
|
|
|
860
865
|
"unvalidated": true,
|
|
861
866
|
"cross_language": false,
|
|
862
867
|
"family": "toctou-file-existence-permission-check-b",
|
|
868
|
+
"parser": "TOCTOU",
|
|
863
869
|
"_unsigned": false,
|
|
864
870
|
"_passThroughSigning": false,
|
|
865
871
|
"signatureStatus": "verified",
|
|
@@ -1053,7 +1059,9 @@
|
|
|
1053
1059
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1054
1060
|
"confidence": "low",
|
|
1055
1061
|
"narrative": "Missing Unsigned Numeric Validation on `agentic-security-audit.js:131` 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."
|
|
1056
|
-
}
|
|
1062
|
+
},
|
|
1063
|
+
"parser": "LOGIC",
|
|
1064
|
+
"family": null
|
|
1057
1065
|
},
|
|
1058
1066
|
{
|
|
1059
1067
|
"id": "logic:agentic-security-audit.js:55:TOCTOU:_existsSync_followed_by_file_op",
|
|
@@ -1134,7 +1142,9 @@
|
|
|
1134
1142
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1135
1143
|
"confidence": "low",
|
|
1136
1144
|
"narrative": "TOCTOU: existsSync followed by file op on `agentic-security-audit.js:55` 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."
|
|
1137
|
-
}
|
|
1145
|
+
},
|
|
1146
|
+
"parser": "LOGIC",
|
|
1147
|
+
"family": null
|
|
1138
1148
|
},
|
|
1139
1149
|
{
|
|
1140
1150
|
"id": "e2445e40b5e43c01",
|
|
@@ -1215,7 +1225,9 @@
|
|
|
1215
1225
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1216
1226
|
"confidence": "low",
|
|
1217
1227
|
"narrative": "Race Condition (TOCTOU) on `agentic-security-consistency.js:66` 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."
|
|
1218
|
-
}
|
|
1228
|
+
},
|
|
1229
|
+
"parser": "LOGIC",
|
|
1230
|
+
"family": null
|
|
1219
1231
|
},
|
|
1220
1232
|
{
|
|
1221
1233
|
"id": "logic:agentic-security-consistency.js:44:TOCTOU:_existsSync_followed_by_file_op",
|
|
@@ -1296,7 +1308,9 @@
|
|
|
1296
1308
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1297
1309
|
"confidence": "low",
|
|
1298
1310
|
"narrative": "TOCTOU: existsSync followed by file op on `agentic-security-consistency.js:44` 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."
|
|
1299
|
-
}
|
|
1311
|
+
},
|
|
1312
|
+
"parser": "LOGIC",
|
|
1313
|
+
"family": null
|
|
1300
1314
|
},
|
|
1301
1315
|
{
|
|
1302
1316
|
"id": "logic:agentic-security-consistency.js:66:TOCTOU:_existsSync_followed_by_file_op",
|
|
@@ -1377,7 +1391,9 @@
|
|
|
1377
1391
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1378
1392
|
"confidence": "low",
|
|
1379
1393
|
"narrative": "TOCTOU: existsSync followed by file op on `agentic-security-consistency.js:66` 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."
|
|
1380
|
-
}
|
|
1394
|
+
},
|
|
1395
|
+
"parser": "LOGIC",
|
|
1396
|
+
"family": null
|
|
1381
1397
|
},
|
|
1382
1398
|
{
|
|
1383
1399
|
"id": "49e1e00962a1950c",
|
|
@@ -1458,7 +1474,9 @@
|
|
|
1458
1474
|
"comparable": "Generic finding — likely cost driven by user count + jurisdiction stack",
|
|
1459
1475
|
"confidence": "low",
|
|
1460
1476
|
"narrative": "Weak Randomness on `agentic-security-rule.js:98` 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."
|
|
1461
|
-
}
|
|
1477
|
+
},
|
|
1478
|
+
"parser": "LOGIC",
|
|
1479
|
+
"family": null
|
|
1462
1480
|
}
|
|
1463
1481
|
],
|
|
1464
1482
|
"bundles": [],
|
|
@@ -1573,5 +1591,6 @@
|
|
|
1573
1591
|
"alarms": [],
|
|
1574
1592
|
"note": "no-feedback-data"
|
|
1575
1593
|
}
|
|
1576
|
-
}
|
|
1594
|
+
},
|
|
1595
|
+
"annotatorErrors": []
|
|
1577
1596
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
ec16cd87a90fed8ff54e93a2bc69d4e8053d22cd80ffc701a4668d3c3e929f7d
|
|
@@ -1,26 +1,4 @@
|
|
|
1
1
|
[
|
|
2
|
-
{
|
|
3
|
-
"timestamp": "2026-05-19T15:44:43.087Z",
|
|
4
|
-
"label": "scan",
|
|
5
|
-
"total": 0,
|
|
6
|
-
"critical": 0,
|
|
7
|
-
"high": 0,
|
|
8
|
-
"medium": 0,
|
|
9
|
-
"low": 0,
|
|
10
|
-
"kev": 0,
|
|
11
|
-
"ids": []
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"timestamp": "2026-05-19T16:01:41.762Z",
|
|
15
|
-
"label": "scan",
|
|
16
|
-
"total": 0,
|
|
17
|
-
"critical": 0,
|
|
18
|
-
"high": 0,
|
|
19
|
-
"medium": 0,
|
|
20
|
-
"low": 0,
|
|
21
|
-
"kev": 0,
|
|
22
|
-
"ids": []
|
|
23
|
-
},
|
|
24
2
|
{
|
|
25
3
|
"timestamp": "2026-05-19T18:33:22.830Z",
|
|
26
4
|
"label": "scan",
|
|
@@ -461,5 +439,37 @@
|
|
|
461
439
|
"toctou-fs:agentic-security-consistency.js:66",
|
|
462
440
|
"toctou-fs:agentic-security.js:1105"
|
|
463
441
|
]
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
"timestamp": "2026-05-21T15:57:04.808Z",
|
|
445
|
+
"label": "scan",
|
|
446
|
+
"total": 4,
|
|
447
|
+
"critical": 0,
|
|
448
|
+
"high": 0,
|
|
449
|
+
"medium": 4,
|
|
450
|
+
"low": 0,
|
|
451
|
+
"kev": 0,
|
|
452
|
+
"ids": [
|
|
453
|
+
"toctou-fs:agentic-security-audit.js:55",
|
|
454
|
+
"toctou-fs:agentic-security-consistency.js:44",
|
|
455
|
+
"toctou-fs:agentic-security-consistency.js:66",
|
|
456
|
+
"toctou-fs:agentic-security.js:1105"
|
|
457
|
+
]
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
"timestamp": "2026-05-21T16:13:41.128Z",
|
|
461
|
+
"label": "scan",
|
|
462
|
+
"total": 4,
|
|
463
|
+
"critical": 0,
|
|
464
|
+
"high": 0,
|
|
465
|
+
"medium": 4,
|
|
466
|
+
"low": 0,
|
|
467
|
+
"kev": 0,
|
|
468
|
+
"ids": [
|
|
469
|
+
"toctou-fs:agentic-security-audit.js:55",
|
|
470
|
+
"toctou-fs:agentic-security-consistency.js:44",
|
|
471
|
+
"toctou-fs:agentic-security-consistency.js:66",
|
|
472
|
+
"toctou-fs:agentic-security.js:1105"
|
|
473
|
+
]
|
|
464
474
|
}
|
|
465
475
|
]
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"firstScanDate": "2026-05-15T12:24:29.316Z",
|
|
3
|
-
"lastScanDate": "2026-05-
|
|
4
|
-
"totalScans":
|
|
5
|
-
"daysCleanCritical":
|
|
6
|
-
"lastCleanDate": "2026-05-
|
|
3
|
+
"lastScanDate": "2026-05-21T16:13:41.148Z",
|
|
4
|
+
"totalScans": 123,
|
|
5
|
+
"daysCleanCritical": 4,
|
|
6
|
+
"lastCleanDate": "2026-05-21",
|
|
7
7
|
"lastCriticalDate": null,
|
|
8
8
|
"hasEverHadCritical": false,
|
|
9
|
-
"bestDaysCleanCritical":
|
|
9
|
+
"bestDaysCleanCritical": 4,
|
|
10
10
|
"totalFindingsAtFirstScan": 0,
|
|
11
11
|
"totalFindingsAtLastScan": 11,
|
|
12
12
|
"totalFixesInferred": 1,
|
package/bin/agentic-security.js
CHANGED
|
@@ -137,7 +137,7 @@ function printBanner(args) {
|
|
|
137
137
|
BOLD: '\x1b[1m',
|
|
138
138
|
RESET: '\x1b[0m',
|
|
139
139
|
} : { FROG:'', DEEP:'', CREAM:'', DIM:'', BOLD:'', RESET:'' };
|
|
140
|
-
const v = '0.
|
|
140
|
+
const v = '0.75.1';
|
|
141
141
|
const compact = !args.flags.full;
|
|
142
142
|
if (compact) {
|
|
143
143
|
const lines = [
|
|
@@ -1665,7 +1665,7 @@ async function main() {
|
|
|
1665
1665
|
}
|
|
1666
1666
|
process.exit(0);
|
|
1667
1667
|
}
|
|
1668
|
-
case 'version': console.log('agentic-security 0.
|
|
1668
|
+
case 'version': console.log('agentic-security 0.75.1 · created by ClearCapabilities.Com'); process.exit(0);
|
|
1669
1669
|
case 'banner': { printBanner(args); process.exit(0); }
|
|
1670
1670
|
case 'harness': process.exit(await cmdHarness(args));
|
|
1671
1671
|
case 'scan-baseline': process.exit(await cmdScanBaseline(args));
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
export const id = 838;
|
|
2
|
+
export const ids = [838];
|
|
3
|
+
export const modules = {
|
|
4
|
+
|
|
5
|
+
/***/ 7838:
|
|
6
|
+
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
|
7
|
+
|
|
8
|
+
__webpack_require__.r(__webpack_exports__);
|
|
9
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
10
|
+
/* harmony export */ runProjectLinter: () => (/* binding */ runProjectLinter),
|
|
11
|
+
/* harmony export */ verifyFix: () => (/* binding */ verifyFix),
|
|
12
|
+
/* harmony export */ verifyPatch: () => (/* binding */ verifyPatch)
|
|
13
|
+
/* harmony export */ });
|
|
14
|
+
/* harmony import */ var node_child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1421);
|
|
15
|
+
/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3024);
|
|
16
|
+
/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6760);
|
|
17
|
+
/* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3291);
|
|
18
|
+
// Closed-loop /fix verification (Sentinel-parity FR-L4-4, FR-L4-5).
|
|
19
|
+
//
|
|
20
|
+
// Given a candidate patch (the new file content + the finding stableId being
|
|
21
|
+
// fixed), verify it:
|
|
22
|
+
//
|
|
23
|
+
// 1. The original finding's stableId no longer fires on the patched file.
|
|
24
|
+
// 2. No new findings at severity ≥ medium were introduced by the patch.
|
|
25
|
+
// 3. The project's existing linter (when present) passes on the patched file.
|
|
26
|
+
//
|
|
27
|
+
// If any of those fail, the caller is expected to NOT apply the patch and
|
|
28
|
+
// instead surface a "fix plan" — a numbered list of steps the engineer can
|
|
29
|
+
// follow — rather than dump a broken patch on the user.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
const SEVERITY_RANK = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
|
|
37
|
+
|
|
38
|
+
// Run a focused re-scan over just the patched file(s) using the in-memory
|
|
39
|
+
// engine. No filesystem write needed — we hand the new content in via the
|
|
40
|
+
// fileContents map.
|
|
41
|
+
async function verifyPatch({
|
|
42
|
+
scanRoot,
|
|
43
|
+
originalFindingStableId,
|
|
44
|
+
files, // { [relPath]: newContent }
|
|
45
|
+
depFileContents = {},
|
|
46
|
+
} = {}) {
|
|
47
|
+
if (!files || typeof files !== 'object') return { ok: false, reason: 'no-files-provided' };
|
|
48
|
+
const fileContents = { ...files };
|
|
49
|
+
let scan;
|
|
50
|
+
try {
|
|
51
|
+
scan = await (0,_engine_js__WEBPACK_IMPORTED_MODULE_3__/* .runFullScan */ .wW)({ fileContents, depFileContents, scanRoot }, () => {});
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return { ok: false, reason: 'rescan-failed', error: e.message };
|
|
54
|
+
}
|
|
55
|
+
const findings = (scan && scan.findings) || [];
|
|
56
|
+
const stillHasOriginal = !!originalFindingStableId &&
|
|
57
|
+
findings.some(f => f.stableId === originalFindingStableId);
|
|
58
|
+
if (stillHasOriginal) {
|
|
59
|
+
return { ok: false, reason: 'original-finding-still-present', stableId: originalFindingStableId };
|
|
60
|
+
}
|
|
61
|
+
const introducedHighOrAbove = findings.filter(f =>
|
|
62
|
+
(SEVERITY_RANK[f.severity] ?? 9) <= SEVERITY_RANK.medium);
|
|
63
|
+
// Don't count findings on lines outside the patched files — but our
|
|
64
|
+
// fileContents map IS the patched files, so every finding is in-scope.
|
|
65
|
+
return {
|
|
66
|
+
ok: introducedHighOrAbove.length === 0,
|
|
67
|
+
reason: introducedHighOrAbove.length === 0 ? 'verified' : 'introduced-new-findings',
|
|
68
|
+
introduced: introducedHighOrAbove.map(f => ({
|
|
69
|
+
vuln: f.vuln, file: f.file, line: f.line, severity: f.severity,
|
|
70
|
+
stableId: f.stableId,
|
|
71
|
+
})),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Detect which linter the project uses and run it on the patched files.
|
|
76
|
+
// Returns { ok, runner, output } or { ok: true, runner: 'none' } when no
|
|
77
|
+
// linter is configured (silent pass).
|
|
78
|
+
function runProjectLinter(scanRoot, filePaths) {
|
|
79
|
+
if (!scanRoot || !Array.isArray(filePaths) || filePaths.length === 0) {
|
|
80
|
+
return { ok: true, runner: 'none' };
|
|
81
|
+
}
|
|
82
|
+
const has = (p) => { try { return node_fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(node_path__WEBPACK_IMPORTED_MODULE_2__.join(scanRoot, p)); } catch { return false; } };
|
|
83
|
+
// Pick the linter by config file present in the repo root.
|
|
84
|
+
const jsFiles = filePaths.filter(f => /\.(?:js|jsx|ts|tsx|mjs|cjs)$/i.test(f));
|
|
85
|
+
const pyFiles = filePaths.filter(f => /\.py$/i.test(f));
|
|
86
|
+
const goFiles = filePaths.filter(f => /\.go$/i.test(f));
|
|
87
|
+
const javaFiles = filePaths.filter(f => /\.java$/i.test(f));
|
|
88
|
+
|
|
89
|
+
if (jsFiles.length && (has('.eslintrc') || has('.eslintrc.json') || has('.eslintrc.js') || has('eslint.config.js') || has('eslint.config.mjs'))) {
|
|
90
|
+
return runLinter(scanRoot, 'eslint', ['--no-error-on-unmatched-pattern', ...jsFiles]);
|
|
91
|
+
}
|
|
92
|
+
if (pyFiles.length && (has('pyproject.toml') || has('ruff.toml') || has('.ruff.toml'))) {
|
|
93
|
+
return runLinter(scanRoot, 'ruff', ['check', ...pyFiles]);
|
|
94
|
+
}
|
|
95
|
+
if (pyFiles.length && has('.flake8')) {
|
|
96
|
+
return runLinter(scanRoot, 'flake8', pyFiles);
|
|
97
|
+
}
|
|
98
|
+
if (goFiles.length && (has('.golangci.yml') || has('.golangci.yaml'))) {
|
|
99
|
+
return runLinter(scanRoot, 'golangci-lint', ['run', ...goFiles]);
|
|
100
|
+
}
|
|
101
|
+
if (javaFiles.length && has('checkstyle.xml')) {
|
|
102
|
+
return runLinter(scanRoot, 'checkstyle', ['-c', 'checkstyle.xml', ...javaFiles]);
|
|
103
|
+
}
|
|
104
|
+
return { ok: true, runner: 'none' };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function runLinter(cwd, cmd, args) {
|
|
108
|
+
let r;
|
|
109
|
+
try {
|
|
110
|
+
r = (0,node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync)(cmd, args, { cwd, encoding: 'utf8', timeout: 60_000 });
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return { ok: true, runner: cmd, skipped: true, reason: 'binary-missing', error: e.message };
|
|
113
|
+
}
|
|
114
|
+
if (r.error && r.error.code === 'ENOENT') {
|
|
115
|
+
return { ok: true, runner: cmd, skipped: true, reason: 'binary-missing' };
|
|
116
|
+
}
|
|
117
|
+
if (r.status === null) {
|
|
118
|
+
return { ok: false, runner: cmd, reason: 'timed-out', output: (r.stderr || r.stdout || '').slice(-2000) };
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
ok: r.status === 0,
|
|
122
|
+
runner: cmd,
|
|
123
|
+
exitCode: r.status,
|
|
124
|
+
output: ((r.stderr || '') + (r.stdout || '')).slice(-2000),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Top-level verify: re-scan + lint. Returns the combined verdict + a
|
|
129
|
+
// human-readable summary string suitable for surfacing to the user.
|
|
130
|
+
async function verifyFix({
|
|
131
|
+
scanRoot,
|
|
132
|
+
originalFindingStableId,
|
|
133
|
+
files,
|
|
134
|
+
depFileContents,
|
|
135
|
+
} = {}) {
|
|
136
|
+
const rescan = await verifyPatch({ scanRoot, originalFindingStableId, files, depFileContents });
|
|
137
|
+
const lint = runProjectLinter(scanRoot, Object.keys(files || {}));
|
|
138
|
+
const ok = rescan.ok && (lint.ok || lint.skipped);
|
|
139
|
+
const summary = [
|
|
140
|
+
`re-scan: ${rescan.ok ? 'PASS' : 'FAIL — ' + rescan.reason}`,
|
|
141
|
+
`linter: ${lint.runner === 'none' ? 'skipped (no linter config)'
|
|
142
|
+
: lint.skipped ? `${lint.runner} not installed`
|
|
143
|
+
: lint.ok ? `${lint.runner} PASS`
|
|
144
|
+
: `${lint.runner} FAIL (exit ${lint.exitCode})`}`,
|
|
145
|
+
].join('\n');
|
|
146
|
+
return { ok, rescan, lint, summary };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
/***/ })
|
|
151
|
+
|
|
152
|
+
};
|