security-mcp 1.1.4 → 1.3.3

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 (158) hide show
  1. package/README.md +341 -1018
  2. package/defaults/checklists/ai.json +20 -1
  3. package/defaults/checklists/api.json +35 -1
  4. package/defaults/checklists/infra.json +34 -1
  5. package/defaults/checklists/mobile.json +23 -1
  6. package/defaults/checklists/payments.json +15 -1
  7. package/defaults/checklists/web.json +11 -1
  8. package/defaults/cloud-controls/aws.json +10712 -0
  9. package/defaults/cloud-controls/azure.json +7201 -0
  10. package/defaults/cloud-controls/gcp.json +4061 -0
  11. package/defaults/control-catalog.json +24 -0
  12. package/defaults/security-policy.json +2 -2
  13. package/dist/ci/pr-gate.js +22 -5
  14. package/dist/cli/index.js +73 -2
  15. package/dist/cli/install.js +4 -55
  16. package/dist/cli/onboarding.js +18 -10
  17. package/dist/gate/baseline.js +82 -7
  18. package/dist/gate/catalog.js +10 -2
  19. package/dist/gate/checks/agentic-instructions.js +515 -0
  20. package/dist/gate/checks/ai-governance.js +132 -0
  21. package/dist/gate/checks/ai.js +757 -39
  22. package/dist/gate/checks/auth-deep.js +920 -216
  23. package/dist/gate/checks/business-logic.js +751 -0
  24. package/dist/gate/checks/ci-pipeline.js +399 -4
  25. package/dist/gate/checks/cloud-controls.js +69 -0
  26. package/dist/gate/checks/crypto.js +423 -2
  27. package/dist/gate/checks/data-platform.js +954 -0
  28. package/dist/gate/checks/dependencies.js +582 -15
  29. package/dist/gate/checks/docker-deep.js +1236 -0
  30. package/dist/gate/checks/gitops.js +724 -0
  31. package/dist/gate/checks/graphql.js +201 -19
  32. package/dist/gate/checks/iac.js +1230 -0
  33. package/dist/gate/checks/infra.js +246 -1
  34. package/dist/gate/checks/injection-deep.js +827 -184
  35. package/dist/gate/checks/k8s.js +955 -2
  36. package/dist/gate/checks/mobile-android.js +917 -3
  37. package/dist/gate/checks/mobile-ios.js +797 -5
  38. package/dist/gate/checks/required-artifacts.js +194 -0
  39. package/dist/gate/checks/runtime.js +178 -0
  40. package/dist/gate/checks/secrets.js +256 -13
  41. package/dist/gate/checks/supply-chain-deep.js +787 -0
  42. package/dist/gate/checks/web-nextjs.js +572 -48
  43. package/dist/gate/cloud-controls/apply.js +115 -0
  44. package/dist/gate/cloud-controls/bicep.js +36 -0
  45. package/dist/gate/cloud-controls/cfn.js +125 -0
  46. package/dist/gate/cloud-controls/detect.js +104 -0
  47. package/dist/gate/cloud-controls/hcl.js +140 -0
  48. package/dist/gate/cloud-controls/types.js +87 -0
  49. package/dist/gate/diff.js +17 -5
  50. package/dist/gate/evidence.js +8 -1
  51. package/dist/gate/exceptions.js +202 -9
  52. package/dist/gate/findings.js +15 -2
  53. package/dist/gate/policy.js +316 -130
  54. package/dist/gate/threat-intel.js +6 -0
  55. package/dist/mcp/audit-chain.js +131 -28
  56. package/dist/mcp/auth.js +169 -0
  57. package/dist/mcp/learning.js +129 -4
  58. package/dist/mcp/model-router.js +161 -24
  59. package/dist/mcp/orchestration.js +377 -89
  60. package/dist/mcp/server.js +460 -69
  61. package/dist/mcp/tool-audit.js +193 -0
  62. package/dist/repo/fs.js +37 -1
  63. package/dist/repo/search.js +31 -6
  64. package/dist/review/store.js +56 -3
  65. package/dist/tests/run.js +124 -1
  66. package/package.json +9 -9
  67. package/skills/_TEMPLATE/SKILL.md +99 -0
  68. package/skills/advanced-dos-tester/SKILL.md +118 -0
  69. package/skills/agentic-instruction-auditor/SKILL.md +111 -0
  70. package/skills/agentic-loop-exploiter/SKILL.md +377 -0
  71. package/skills/ai-llm-redteam/SKILL.md +113 -0
  72. package/skills/ai-model-supply-chain-agent/SKILL.md +112 -0
  73. package/skills/algorithm-implementation-reviewer/SKILL.md +107 -0
  74. package/skills/android-penetration-tester/SKILL.md +464 -46
  75. package/skills/anti-replay-tester/SKILL.md +115 -0
  76. package/skills/appsec-code-auditor/SKILL.md +94 -0
  77. package/skills/artifact-integrity-analyst/SKILL.md +450 -0
  78. package/skills/attack-navigator/SKILL.md +476 -8
  79. package/skills/auth-session-hacker/SKILL.md +111 -0
  80. package/skills/aws-penetration-tester/SKILL.md +510 -0
  81. package/skills/azure-penetration-tester/SKILL.md +542 -3
  82. package/skills/binary-auth-validator/SKILL.md +120 -0
  83. package/skills/bot-detection-specialist/SKILL.md +118 -0
  84. package/skills/business-logic-attacker/SKILL.md +240 -0
  85. package/skills/capec-code-mapper/SKILL.md +93 -0
  86. package/skills/cert-pin-rotation-specialist/SKILL.md +121 -0
  87. package/skills/cicd-pipeline-hijacker/SKILL.md +414 -0
  88. package/skills/ciso-orchestrator/SKILL.md +465 -43
  89. package/skills/cloud-infra-specialist/SKILL.md +127 -0
  90. package/skills/compliance-gap-analyst/SKILL.md +431 -0
  91. package/skills/compliance-grc/SKILL.md +94 -0
  92. package/skills/compliance-lifecycle-tracker/SKILL.md +93 -0
  93. package/skills/container-hardening-auditor/SKILL.md +125 -0
  94. package/skills/credential-stuffing-specialist/SKILL.md +111 -0
  95. package/skills/crypto-pki-specialist/SKILL.md +96 -0
  96. package/skills/csa-ccm-mapper/SKILL.md +93 -0
  97. package/skills/csf2-governance-mapper/SKILL.md +93 -0
  98. package/skills/data-platform-auditor/SKILL.md +125 -0
  99. package/skills/deep-link-fuzzer/SKILL.md +118 -0
  100. package/skills/dependency-confusion-attacker/SKILL.md +424 -0
  101. package/skills/device-integrity-aggregator/SKILL.md +117 -0
  102. package/skills/dos-resilience-tester/SKILL.md +106 -0
  103. package/skills/dread-scorer/SKILL.md +93 -0
  104. package/skills/egress-policy-enforcer/SKILL.md +108 -0
  105. package/skills/evidence-collector/SKILL.md +107 -0
  106. package/skills/file-upload-attacker/SKILL.md +118 -0
  107. package/skills/gcp-penetration-tester/SKILL.md +510 -2
  108. package/skills/git-history-secret-scanner/SKILL.md +115 -0
  109. package/skills/gitops-delivery-auditor/SKILL.md +120 -0
  110. package/skills/iac-security-auditor/SKILL.md +125 -0
  111. package/skills/iam-privesc-graph-builder/SKILL.md +161 -0
  112. package/skills/incident-responder/SKILL.md +120 -0
  113. package/skills/injection-specialist/SKILL.md +111 -0
  114. package/skills/ios-security-auditor/SKILL.md +291 -0
  115. package/skills/json-ambiguity-tester/SKILL.md +145 -0
  116. package/skills/k8s-container-escaper/SKILL.md +406 -0
  117. package/skills/key-management-lifecycle-analyst/SKILL.md +107 -0
  118. package/skills/kill-switch-engineer/SKILL.md +111 -0
  119. package/skills/linddun-privacy-analyst/SKILL.md +111 -0
  120. package/skills/logic-race-fuzzer/SKILL.md +452 -0
  121. package/skills/mobile-api-network-attacker/SKILL.md +430 -0
  122. package/skills/mobile-binary-hardener/SKILL.md +111 -0
  123. package/skills/mobile-security-specialist/SKILL.md +94 -0
  124. package/skills/mobile-webview-auditor/SKILL.md +105 -0
  125. package/skills/model-extraction-attacker/SKILL.md +228 -0
  126. package/skills/multipart-abuse-tester/SKILL.md +93 -0
  127. package/skills/oauth-pkce-specialist/SKILL.md +113 -0
  128. package/skills/parser-exhaustion-tester/SKILL.md +151 -0
  129. package/skills/pentest-infra/SKILL.md +107 -0
  130. package/skills/pentest-social/SKILL.md +210 -0
  131. package/skills/pentest-team/SKILL.md +96 -0
  132. package/skills/pentest-web-api/SKILL.md +107 -0
  133. package/skills/privacy-flow-analyst/SKILL.md +243 -0
  134. package/skills/prompt-injection-specialist/SKILL.md +403 -0
  135. package/skills/quantum-migration-planner/SKILL.md +105 -0
  136. package/skills/rag-poisoning-specialist/SKILL.md +367 -0
  137. package/skills/registry-mirror-enforcer/SKILL.md +93 -0
  138. package/skills/rotation-validation-agent/SKILL.md +121 -0
  139. package/skills/samm-assessor/SKILL.md +94 -0
  140. package/skills/secrets-mask-bypass-tester/SKILL.md +109 -0
  141. package/skills/senior-security-engineer/SKILL.md +178 -0
  142. package/skills/serialization-memory-attacker/SKILL.md +341 -0
  143. package/skills/session-timeout-tester/SKILL.md +170 -0
  144. package/skills/slsa-level3-enforcer/SKILL.md +121 -0
  145. package/skills/slsa-provenance-enforcer/SKILL.md +111 -0
  146. package/skills/ssrf-detection-validator/SKILL.md +117 -0
  147. package/skills/step-up-auth-enforcer/SKILL.md +93 -0
  148. package/skills/stride-pasta-analyst/SKILL.md +429 -0
  149. package/skills/supply-chain-devsecops/SKILL.md +107 -0
  150. package/skills/threat-infrastructure-analyst/SKILL.md +93 -0
  151. package/skills/threat-modeler/SKILL.md +94 -0
  152. package/skills/tls-certificate-auditor/SKILL.md +582 -18
  153. package/skills/token-reuse-detector/SKILL.md +104 -0
  154. package/skills/trike-risk-modeler/SKILL.md +93 -0
  155. package/skills/unicode-homograph-tester/SKILL.md +93 -0
  156. package/skills/waf-rule-lifecycle-agent/SKILL.md +106 -0
  157. package/skills/webhook-security-tester/SKILL.md +111 -0
  158. package/skills/zero-trust-architect/SKILL.md +118 -0
@@ -34,6 +34,15 @@ On every finding resolved, emit:
34
34
  }
35
35
  ```
36
36
 
37
+ ## BEYOND THE CHECKS — AUTONOMOUS DETECT & FIX
38
+
39
+ The `injection-deep` + `api` detection modules (`src/gate/checks/injection-deep.ts`, `src/gate/checks/api.ts`) are your deterministic floor, not your ceiling. Treat their finding IDs as the minimum, then reason past single-line/single-file pattern matching — and APPLY the fix (Edit), not just advise:
40
+
41
+ - **Cross-file / data-flow reasoning the regex can't do:** a magic-byte check at the upload handler is bypassed if a separate thumbnail Lambda or CDN edge worker fetches the raw object from storage and renders it — trace the uploaded file from the upload route through storage to every downstream consumer (resizer, PDF extractor, archive unzipper) across files.
42
+ - **Semantic / effective-state analysis:** model the upload taint chain — `originalname` → `path.join` (traversal), archive entry → symlink target (ZIP Slip via symlink, not just `../`), SVG `<image href>` → IMDS (SSRF), compression ratio → OOM (nested-archive bomb). Compute the effective execution context (same-origin serving = XSS/exec), not just the declared Content-Type.
43
+ - **External corroboration:** WebSearch/WebFetch + OSV.dev for current CVEs in file-processing libs (`sharp`/ImageMagick/libvips) and polyglot-weaponisation advisories.
44
+ - **Apply & prove:** write the fix inline (magic-byte allowlist, filename sanitisation, symlink-aware ZIP Slip guard, ratio cap, `Content-Disposition: attachment`, isolated serving origin), re-run the `injection-deep`/`api` checks plus `semgrep` and an `osv-scanner` sweep of image libs as a regression floor, then re-audit. Emit the LEARNING SIGNAL per fix; surface trade-offs with the secure default.
45
+
37
46
  ## EXECUTION
38
47
 
39
48
  ### Phase 1 — Reconnaissance
@@ -206,3 +215,112 @@ function checkArchiveBomb(compressedSize: number, uncompressedSize: number): voi
206
215
  - `requiredActions`: ordered action list
207
216
  - `complianceImpact`: framework mappings
208
217
  - `beyondSkillMd`: true if finding goes beyond the SKILL.md mandate
218
+
219
+ Every findings JSON MUST include `intelligenceForOtherAgents`:
220
+ ```json
221
+ {
222
+ "intelligenceForOtherAgents": {
223
+ "forPentestTeam": [{ "type": "HIGH_VALUE_TARGET", "description": "Upload endpoint accepts arbitrary filenames — manual ZIP Slip PoC advised", "exploitHint": "Craft zip with ../../../../.env entry and POST to /api/upload" }],
224
+ "forCryptoSpecialist": [{ "type": "CRYPTO_WEAKNESS_REFERENCE", "algorithm": "MD5 used for dedup hash of uploaded files", "location": "src/storage/fileDedup.ts" }],
225
+ "forCloudSpecialist": [{ "type": "SSRF_TO_CLOUD_CHAIN", "ssrfLocation": "Upload handler fetches remote URL for image import — no SSRF guard", "escalationPath": "Fetch http://169.254.169.254/latest/meta-data/ to exfiltrate IAM credentials" }],
226
+ "forComplianceGrc": [{ "type": "COMPLIANCE_BLOCKER", "frameworks": ["PCI-DSS Req 6.2.4", "SOC 2 CC6.1"], "releaseBlock": true }]
227
+ }
228
+ }
229
+ ```
230
+
231
+ ---
232
+
233
+ ## BEYOND SKILL.MD — MANDATORY EXPANSIONS
234
+
235
+ - **AI-Generated Polyglot File Weaponisation (CWE-434 / ATT&CK T1190):** LLM-assisted tooling (e.g., PolyglotGen, custom GPT wrappers) auto-crafts files that simultaneously satisfy two parsers — a valid JPEG (JFIF header + EOI marker) with a PHP or Python webshell payload appended. Signature scanners match only the leading magic bytes and pass the file. Test by: upload a file produced with `polyglot-php-jpg` or manually appending `<?php system($_GET['cmd']); ?>` after the JPEG EOI (`\xFF\xD9`) marker, then request it at its storage URL with `?cmd=id`. Finding threshold: server executes the payload or returns non-404 with PHP output rather than serving raw bytes.
236
+
237
+ - **ZIP Slip via Symlink Entry (CVE-2018-1002200 / ATT&CK T1083):** Standard path-traversal guards check `entry.name` for `../` sequences but do not verify symlink targets inside archives. A zip entry `link -> ../../../../etc/cron.d/` (symlink) followed by `link/backdoor` (regular file) passes the `isZipSlip` check on entry names, yet extraction writes `backdoor` to `/etc/cron.d/`. Test by: craft an archive with Python's `zipfile` module adding a `ZipInfo` with `external_attr = 0xA1ED0000` (symlink flag) pointing to a sensitive directory, then POST to the archive extraction endpoint. Finding threshold: file appears outside the designated extraction root, or the `isSymlink()` check is absent from extraction code.
238
+
239
+ - **SVG SSRF via Thumbnail Pipeline Bypassing API-Layer Blocks (CVE-2022-44268 analogue / ATT&CK T1552.007):** The application-layer upload endpoint correctly rejects `image/svg+xml`, but a separate image-resizing Lambda or CDN edge function fetches and renders SVGs directly from the object storage bucket, bypassing all application controls. Payload: `<svg xmlns="http://www.w3.org/2000/svg"><image href="http://169.254.169.254/latest/meta-data/iam/security-credentials/"/></svg>`. Test by: upload the SVG directly to the storage bucket (bypassing the API) and trigger thumbnail generation via the CDN URL or resizing endpoint; monitor egress with a Burp Collaborator / interactsh callback. Finding threshold: HTTP request received at the callback host from the thumbnail worker IP range, or IMDSv1 credentials returned in the rendered output.
240
+
241
+ - **Supply Chain Risk in File-Processing Libraries — ImageMagick / libvips CVE Churn (CVE-2023-34152, CVE-2024-28219):** ImageMagick and libvips have a persistent history of RCE and arbitrary file-read CVEs triggered by crafted image inputs (e.g., CVE-2023-34152: shell injection via filename passed to external delegate, CVE-2024-28219: buffer overflow in libvips TIFF decoder). Any Node.js service using `sharp`, `jimp`, or `gm` transitively depends on these libraries. Test by: run `npm ls sharp imagemagick gm` to enumerate transitive image-processing deps; cross-reference installed version against OSV.dev (`https://api.osv.dev/v1/query`) for open CVEs; attempt a CVE-2016-3714-style `|id` filename in the upload if using older ImageMagick. Finding threshold: installed library version has any open CVE with CVSS >= 7.0, or SBOM generation (`cyclonedx-npm`) is absent from the CI pipeline.
242
+
243
+ - **Archive Bomb Nested Inside Allowed Container Format — Zip-in-PNG (CWE-400 / OWASP A05:2021):** A zip bomb is embedded as a PNG comment block or PDF attachment stream. The file passes magic-byte MIME validation (leading bytes are valid PNG or PDF), raw compressed size is within the upload limit, and antivirus scanners check only the outer container. The bomb detonates when a downstream thumbnail generator or PDF text-extractor recursively decompresses the inner archive. Test by: create a PNG with a `zTXt` chunk containing a 42.zip-style recursive deflate bomb (1 KB compressed, 4.5 PB uncompressed); upload as `photo.png`; trigger thumbnail generation and monitor worker disk/memory usage via CloudWatch or cgroups metrics. Finding threshold: worker process OOM-killed or disk usage spikes >10x the compressed upload size within 5 seconds of processing.
244
+
245
+ - **Regulatory Gap — EU CRA / US EO 14028 SBOM Mandate for File-Processing Dependencies (ATT&CK T1195.001):** The EU Cyber Resilience Act (CRA, effective 2027) and US Executive Order 14028 require a machine-readable SBOM for any software handling user-uploaded content. File-processing libraries (libmagic, libarchive, Pillow, ImageMagick) are high-churn CVE surfaces that must appear in CycloneDX or SPDX SBOMs with exact version and license. Absence of SBOM generation in CI is itself a compliance gap. Test by: run `cyclonedx-npm --output sbom.json` (Node) or `cyclonedx-py --output sbom.json` (Python) and verify every file-processing dependency is enumerated; then query `https://api.osv.dev/v1/query` for each component. Finding threshold: any file-processing library absent from SBOM, or any SBOM component with an open CVE that has no documented remediation timeline in the project's risk register.
246
+
247
+ ---
248
+
249
+ ## §EDGE-CASE-MATRIX
250
+
251
+ The 5 file-upload attack cases that automated scanners and naive manual review universally miss. MANDATORY checks — do not skip.
252
+
253
+ | # | Edge Case | Why Scanners Miss It | Concrete Test |
254
+ |---|-----------|----------------------|---------------|
255
+ | 1 | Polyglot file valid in two formats simultaneously | Scanner validates magic bytes for one format only; browser or server consumes it as the other | Craft a file that is simultaneously a valid JPEG (JFIF header) and a valid JavaScript module or PHP script (payload appended after EOI marker); upload as `photo.jpg`, then request with `Accept: text/javascript` or rename via a second request |
256
+ | 2 | Double-extension + null byte bypass | Regex checks `\.jpg$` and matches; server strips at null byte leaving `.php` | Upload `evil.php\x00.jpg` (URL-encoded `%00`) — on older stacks the null terminates the OS filename string, storing `evil.php` |
257
+ | 3 | ZIP Slip via symlink inside archive | Path-traversal check validates entry names but not symlink targets; extractor follows symlink into sensitive dir | Create zip containing `link -> ../../../etc/cron.d/` (symlink entry) then `link/pwn` (file); standard `isZipSlip` check on the symlink name passes, but extraction writes outside destDir |
258
+ | 4 | SVG with external entity / SSRF via `<image href>` | Scanner checks `image/svg+xml` is blocked globally but misses SVG accepted as "document" upload or in a separate endpoint | Upload `<svg><image href="http://169.254.169.254/latest/meta-data/"/>` as `.svg`; if server renders or thumbnails it, SSRF hits IMDSv1 |
259
+ | 5 | Archive bomb nested inside allowed image format | Virus scanner and size check run on the raw compressed bytes; uncompressed size only visible after extraction | Embed a `zip` inside a valid PNG comment block or PDF attachment stream — file passes magic-byte MIME check and raw-size limit; extraction triggers resource exhaustion |
260
+
261
+ ---
262
+
263
+ ## §TEMPORAL-THREATS
264
+
265
+ Threats materialising in the 2025–2030 window that defences around file upload must account for today.
266
+
267
+ | Threat | Est. Timeline | Relevance to File Upload | Prepare Now By |
268
+ |--------|--------------|--------------------------|----------------|
269
+ | AI-generated polyglot weaponisation at scale | 2025–2027 (active) | LLM tooling auto-generates polyglot files (PDF+PHP, PNG+JS) that evade static signature scanners | Adopt content-aware server-side scanning (ClamAV + YARA rules updated weekly); never trust magic bytes alone |
270
+ | Mandatory SBOM + build provenance (US EO 14028 / EU CRA) | 2025–2026 (active) | File processing libraries (libmagic, libarchive, imagemagick) must appear in SBOM; CVEs surface fast | Generate CycloneDX SBOM per release; subscribe to OSV feeds for all file-processing dependencies |
271
+ | EU AI Act enforcement for AI-powered content moderation | 2026 | If upload pipeline uses AI to classify or moderate content, it becomes a regulated AI system | Classify AI moderation components against AI Act risk tiers now; document human oversight procedures |
272
+ | Cryptographically Relevant Quantum Computer (CRQC) | 2028–2032 | File integrity signatures (RSA/ECDSA over upload manifests) breakable retroactively | Migrate file-signing to ML-DSA (FIPS 204); inventory all RSA/ECDSA usage in upload verification |
273
+ | Post-quantum TLS migration deadline | 2028–2030 | Files in transit protected only by classical TLS will be exposed by harvest-now-decrypt-later | Begin TLS agility assessment for upload endpoints; test hybrid key exchange (X25519+ML-KEM) |
274
+
275
+ ---
276
+
277
+ ## §DETECTION-GAP
278
+
279
+ What current security monitoring CANNOT detect in the file-upload domain, and what to build to close each gap.
280
+
281
+ - **Polyglot file execution in downstream consumer**: The upload request looks like a valid JPEG (200 OK, magic bytes pass). The dangerous execution happens when a downstream renderer, thumbnail generator, or CDN edge worker processes the file. Monitoring only the upload endpoint misses this. Need: instrument file-processing workers to emit an event per file type inferred at execution time; alert when execution-time MIME differs from upload-time MIME.
282
+
283
+ - **ZIP Slip via symlink**: Standard ZIP entry path checks validate names but not symlink targets. A symlink-based ZIP Slip leaves no anomalous path string in logs — the entry name looks safe. Need: add a YARA or custom rule that flags zip/tar archives containing symlink entries (`entry.isSymlink()`) before extraction; log and quarantine immediately.
284
+
285
+ - **SVG SSRF from thumbnail pipeline**: The upload is rejected at the API boundary, but a misconfigured CDN or image-resizing Lambda still fetches and renders SVG from the storage bucket directly, bypassing application-layer controls. No application log event emitted. Need: monitor egress from image-processing infrastructure (VPC flow logs / CloudTrail); alert on outbound HTTP from thumbnail workers to RFC 1918 addresses or IMDSv2 endpoints.
286
+
287
+ - **Archive bomb detonation during lazy extraction**: Size and ratio checks pass on the compressed archive (within limits). Extraction is deferred to a background job. By the time the bomb expands, the request is long complete — rate limiting and request-level WAF rules do not trigger. Need: enforce extraction quotas inside the background worker (inotify / disk-usage polling); kill and quarantine extraction jobs that exceed the uncompressed size budget mid-stream.
288
+
289
+ - **Filename-based path traversal after rename**: Initial upload sanitises the filename. A subsequent rename or move API call re-introduces the original user-supplied name (e.g., from a metadata field stored at upload time). The traversal happens in the rename step, not the upload step. Need: re-validate sanitisation rules at every file-system operation that uses the filename, not just at upload time; treat stored `originalname` fields as untrusted input at every use site.
290
+
291
+ ---
292
+
293
+ ## §ZERO-MISS-MANDATE
294
+
295
+ This agent CANNOT declare any file-upload attack class clean without explicit evidence of checking. For each item, output one of:
296
+ - `CHECKED: [N files] | [patterns used] | CLEAN`
297
+ - `CHECKED: [N files] | [patterns used] | [N findings, all fixed]`
298
+ - `SKIPPED: [reason — must be "not applicable: [evidence]"]`
299
+
300
+ **Silent skip = FAILED COVERAGE.** The orchestrator flags this as a quality gap.
301
+
302
+ Attack classes that MUST be evidenced:
303
+ - Magic-byte / MIME type validation
304
+ - ZIP Slip (path traversal in archive extraction)
305
+ - Archive bomb (compression ratio + uncompressed size limit)
306
+ - SVG XSS and SVG SSRF
307
+ - Filename sanitisation (null bytes, double extensions, path separators)
308
+ - Polyglot file bypass
309
+ - Stored file access control (auth required to retrieve, Content-Disposition enforced)
310
+ - Upload-origin isolation (separate domain or CDN origin for served files)
311
+
312
+ The output findings JSON MUST include a `coverageManifest` key:
313
+ ```json
314
+ {
315
+ "coverageManifest": {
316
+ "attackClassesCovered": [
317
+ { "class": "MIME Magic-Byte Validation", "filesReviewed": 12, "patterns": ["fileTypeFromBuffer", "magic", "mmmagic"], "result": "CLEAN" },
318
+ { "class": "ZIP Slip", "filesReviewed": 4, "patterns": ["path.resolve", "startsWith(destDir)", "adm-zip", "unzip"], "result": "2 findings, all fixed" },
319
+ { "class": "SVG XSS / SSRF", "filesReviewed": 12, "patterns": ["image/svg+xml", ".svg", "ALLOWED_MIME_TYPES"], "result": "CLEAN" }
320
+ ],
321
+ "filesReviewed": 28,
322
+ "negativeAssertions": ["SVG MIME type absent from ALLOWED_MIME_TYPES across all 12 upload handler files"],
323
+ "uncoveredReason": {}
324
+ }
325
+ }
326
+ ```