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.
- package/README.md +341 -1018
- package/defaults/checklists/ai.json +20 -1
- package/defaults/checklists/api.json +35 -1
- package/defaults/checklists/infra.json +34 -1
- package/defaults/checklists/mobile.json +23 -1
- package/defaults/checklists/payments.json +15 -1
- package/defaults/checklists/web.json +11 -1
- package/defaults/cloud-controls/aws.json +10712 -0
- package/defaults/cloud-controls/azure.json +7201 -0
- package/defaults/cloud-controls/gcp.json +4061 -0
- package/defaults/control-catalog.json +24 -0
- package/defaults/security-policy.json +2 -2
- package/dist/ci/pr-gate.js +22 -5
- package/dist/cli/index.js +73 -2
- package/dist/cli/install.js +4 -55
- package/dist/cli/onboarding.js +18 -10
- package/dist/gate/baseline.js +82 -7
- package/dist/gate/catalog.js +10 -2
- package/dist/gate/checks/agentic-instructions.js +515 -0
- package/dist/gate/checks/ai-governance.js +132 -0
- package/dist/gate/checks/ai.js +757 -39
- package/dist/gate/checks/auth-deep.js +920 -216
- package/dist/gate/checks/business-logic.js +751 -0
- package/dist/gate/checks/ci-pipeline.js +399 -4
- package/dist/gate/checks/cloud-controls.js +69 -0
- package/dist/gate/checks/crypto.js +423 -2
- package/dist/gate/checks/data-platform.js +954 -0
- package/dist/gate/checks/dependencies.js +582 -15
- package/dist/gate/checks/docker-deep.js +1236 -0
- package/dist/gate/checks/gitops.js +724 -0
- package/dist/gate/checks/graphql.js +201 -19
- package/dist/gate/checks/iac.js +1230 -0
- package/dist/gate/checks/infra.js +246 -1
- package/dist/gate/checks/injection-deep.js +827 -184
- package/dist/gate/checks/k8s.js +955 -2
- package/dist/gate/checks/mobile-android.js +917 -3
- package/dist/gate/checks/mobile-ios.js +797 -5
- package/dist/gate/checks/required-artifacts.js +194 -0
- package/dist/gate/checks/runtime.js +178 -0
- package/dist/gate/checks/secrets.js +256 -13
- package/dist/gate/checks/supply-chain-deep.js +787 -0
- package/dist/gate/checks/web-nextjs.js +572 -48
- package/dist/gate/cloud-controls/apply.js +115 -0
- package/dist/gate/cloud-controls/bicep.js +36 -0
- package/dist/gate/cloud-controls/cfn.js +125 -0
- package/dist/gate/cloud-controls/detect.js +104 -0
- package/dist/gate/cloud-controls/hcl.js +140 -0
- package/dist/gate/cloud-controls/types.js +87 -0
- package/dist/gate/diff.js +17 -5
- package/dist/gate/evidence.js +8 -1
- package/dist/gate/exceptions.js +202 -9
- package/dist/gate/findings.js +15 -2
- package/dist/gate/policy.js +316 -130
- package/dist/gate/threat-intel.js +6 -0
- package/dist/mcp/audit-chain.js +131 -28
- package/dist/mcp/auth.js +169 -0
- package/dist/mcp/learning.js +129 -4
- package/dist/mcp/model-router.js +161 -24
- package/dist/mcp/orchestration.js +377 -89
- package/dist/mcp/server.js +460 -69
- package/dist/mcp/tool-audit.js +193 -0
- package/dist/repo/fs.js +37 -1
- package/dist/repo/search.js +31 -6
- package/dist/review/store.js +56 -3
- package/dist/tests/run.js +124 -1
- package/package.json +9 -9
- package/skills/_TEMPLATE/SKILL.md +99 -0
- package/skills/advanced-dos-tester/SKILL.md +118 -0
- package/skills/agentic-instruction-auditor/SKILL.md +111 -0
- package/skills/agentic-loop-exploiter/SKILL.md +377 -0
- package/skills/ai-llm-redteam/SKILL.md +113 -0
- package/skills/ai-model-supply-chain-agent/SKILL.md +112 -0
- package/skills/algorithm-implementation-reviewer/SKILL.md +107 -0
- package/skills/android-penetration-tester/SKILL.md +464 -46
- package/skills/anti-replay-tester/SKILL.md +115 -0
- package/skills/appsec-code-auditor/SKILL.md +94 -0
- package/skills/artifact-integrity-analyst/SKILL.md +450 -0
- package/skills/attack-navigator/SKILL.md +476 -8
- package/skills/auth-session-hacker/SKILL.md +111 -0
- package/skills/aws-penetration-tester/SKILL.md +510 -0
- package/skills/azure-penetration-tester/SKILL.md +542 -3
- package/skills/binary-auth-validator/SKILL.md +120 -0
- package/skills/bot-detection-specialist/SKILL.md +118 -0
- package/skills/business-logic-attacker/SKILL.md +240 -0
- package/skills/capec-code-mapper/SKILL.md +93 -0
- package/skills/cert-pin-rotation-specialist/SKILL.md +121 -0
- package/skills/cicd-pipeline-hijacker/SKILL.md +414 -0
- package/skills/ciso-orchestrator/SKILL.md +465 -43
- package/skills/cloud-infra-specialist/SKILL.md +127 -0
- package/skills/compliance-gap-analyst/SKILL.md +431 -0
- package/skills/compliance-grc/SKILL.md +94 -0
- package/skills/compliance-lifecycle-tracker/SKILL.md +93 -0
- package/skills/container-hardening-auditor/SKILL.md +125 -0
- package/skills/credential-stuffing-specialist/SKILL.md +111 -0
- package/skills/crypto-pki-specialist/SKILL.md +96 -0
- package/skills/csa-ccm-mapper/SKILL.md +93 -0
- package/skills/csf2-governance-mapper/SKILL.md +93 -0
- package/skills/data-platform-auditor/SKILL.md +125 -0
- package/skills/deep-link-fuzzer/SKILL.md +118 -0
- package/skills/dependency-confusion-attacker/SKILL.md +424 -0
- package/skills/device-integrity-aggregator/SKILL.md +117 -0
- package/skills/dos-resilience-tester/SKILL.md +106 -0
- package/skills/dread-scorer/SKILL.md +93 -0
- package/skills/egress-policy-enforcer/SKILL.md +108 -0
- package/skills/evidence-collector/SKILL.md +107 -0
- package/skills/file-upload-attacker/SKILL.md +118 -0
- package/skills/gcp-penetration-tester/SKILL.md +510 -2
- package/skills/git-history-secret-scanner/SKILL.md +115 -0
- package/skills/gitops-delivery-auditor/SKILL.md +120 -0
- package/skills/iac-security-auditor/SKILL.md +125 -0
- package/skills/iam-privesc-graph-builder/SKILL.md +161 -0
- package/skills/incident-responder/SKILL.md +120 -0
- package/skills/injection-specialist/SKILL.md +111 -0
- package/skills/ios-security-auditor/SKILL.md +291 -0
- package/skills/json-ambiguity-tester/SKILL.md +145 -0
- package/skills/k8s-container-escaper/SKILL.md +406 -0
- package/skills/key-management-lifecycle-analyst/SKILL.md +107 -0
- package/skills/kill-switch-engineer/SKILL.md +111 -0
- package/skills/linddun-privacy-analyst/SKILL.md +111 -0
- package/skills/logic-race-fuzzer/SKILL.md +452 -0
- package/skills/mobile-api-network-attacker/SKILL.md +430 -0
- package/skills/mobile-binary-hardener/SKILL.md +111 -0
- package/skills/mobile-security-specialist/SKILL.md +94 -0
- package/skills/mobile-webview-auditor/SKILL.md +105 -0
- package/skills/model-extraction-attacker/SKILL.md +228 -0
- package/skills/multipart-abuse-tester/SKILL.md +93 -0
- package/skills/oauth-pkce-specialist/SKILL.md +113 -0
- package/skills/parser-exhaustion-tester/SKILL.md +151 -0
- package/skills/pentest-infra/SKILL.md +107 -0
- package/skills/pentest-social/SKILL.md +210 -0
- package/skills/pentest-team/SKILL.md +96 -0
- package/skills/pentest-web-api/SKILL.md +107 -0
- package/skills/privacy-flow-analyst/SKILL.md +243 -0
- package/skills/prompt-injection-specialist/SKILL.md +403 -0
- package/skills/quantum-migration-planner/SKILL.md +105 -0
- package/skills/rag-poisoning-specialist/SKILL.md +367 -0
- package/skills/registry-mirror-enforcer/SKILL.md +93 -0
- package/skills/rotation-validation-agent/SKILL.md +121 -0
- package/skills/samm-assessor/SKILL.md +94 -0
- package/skills/secrets-mask-bypass-tester/SKILL.md +109 -0
- package/skills/senior-security-engineer/SKILL.md +178 -0
- package/skills/serialization-memory-attacker/SKILL.md +341 -0
- package/skills/session-timeout-tester/SKILL.md +170 -0
- package/skills/slsa-level3-enforcer/SKILL.md +121 -0
- package/skills/slsa-provenance-enforcer/SKILL.md +111 -0
- package/skills/ssrf-detection-validator/SKILL.md +117 -0
- package/skills/step-up-auth-enforcer/SKILL.md +93 -0
- package/skills/stride-pasta-analyst/SKILL.md +429 -0
- package/skills/supply-chain-devsecops/SKILL.md +107 -0
- package/skills/threat-infrastructure-analyst/SKILL.md +93 -0
- package/skills/threat-modeler/SKILL.md +94 -0
- package/skills/tls-certificate-auditor/SKILL.md +582 -18
- package/skills/token-reuse-detector/SKILL.md +104 -0
- package/skills/trike-risk-modeler/SKILL.md +93 -0
- package/skills/unicode-homograph-tester/SKILL.md +93 -0
- package/skills/waf-rule-lifecycle-agent/SKILL.md +106 -0
- package/skills/webhook-security-tester/SKILL.md +111 -0
- package/skills/zero-trust-architect/SKILL.md +118 -0
|
@@ -22,6 +22,15 @@ Find every key management gap: hardcoded keys, unrotated keys, over-scoped keys,
|
|
|
22
22
|
key hierarchy, and post-quantum readiness. Write secrets manager configurations and rotation
|
|
23
23
|
scripts inline.
|
|
24
24
|
|
|
25
|
+
## BEYOND THE CHECKS — AUTONOMOUS DETECT & FIX
|
|
26
|
+
|
|
27
|
+
The `crypto.ts` detection module (`src/gate/checks/crypto.ts`) — keys/TLS/algorithms — is your deterministic floor, not your ceiling. Treat its finding IDs as the minimum, then reason past single-line/single-file pattern matching — and APPLY the fix (Edit), not just advise:
|
|
28
|
+
|
|
29
|
+
- **Cross-file / data-flow reasoning the regex can't do:** a `JWT_SECRET` flagged in one `.env` is only the start — trace the same value across `docker-compose.yml`, k8s `Secret` manifests, CI env vars, and git history, since a "rotated" key reused elsewhere defeats rotation entirely. Confirm DEK/KEK separation by following the key material from generation through every use site, not just the declaration.
|
|
30
|
+
- **Semantic / effective-state analysis:** a key in AWS Secrets Manager with a rotation Lambda *configured* but a `kid`-less JWT verifier still trusts old tokens forever; an HSM-backed key whose policy has `Principal: "*"` is effectively public. Judge the effective blast radius and rotation behavior, not the presence of a secrets-manager reference.
|
|
31
|
+
- **External corroboration:** WebSearch/WebFetch current NIST PQC status (FIPS 203/204/205), NIST 800-57, and CVEs for the detected crypto libraries (e.g. Psychic Signatures CVE-2022-21449, XZ CVE-2024-3094) before scoring long-lived keys.
|
|
32
|
+
- **Apply & prove:** write the secrets-manager reference, rotation script, and HKDF hierarchy inline, then re-run `src/gate/checks/crypto.ts` plus `trufflehog --only-verified` and `gitleaks` as a regression floor, then re-audit git history. Emit the LEARNING SIGNAL per fix; surface trade-offs (e.g. short DEK cache TTL increasing KMS call cost) against the secure default.
|
|
33
|
+
|
|
25
34
|
## EXECUTION
|
|
26
35
|
|
|
27
36
|
1. **Hardcoded key detection (CRITICAL for any match):**
|
|
@@ -90,3 +99,101 @@ If internet permitted:
|
|
|
90
99
|
- Fixed configuration: secrets manager reference, rotation schedule
|
|
91
100
|
- Post-quantum risk assessment for long-lived keys
|
|
92
101
|
- CWE, CVSSv4
|
|
102
|
+
|
|
103
|
+
Every findings JSON MUST include `intelligenceForOtherAgents`:
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"intelligenceForOtherAgents": {
|
|
107
|
+
"forPentestTeam": [{ "type": "HIGH_VALUE_TARGET", "description": "...", "exploitHint": "..." }],
|
|
108
|
+
"forCryptoSpecialist": [{ "type": "CRYPTO_WEAKNESS_REFERENCE", "algorithm": "...", "location": "..." }],
|
|
109
|
+
"forCloudSpecialist": [{ "type": "SSRF_TO_CLOUD_CHAIN", "ssrfLocation": "...", "escalationPath": "..." }],
|
|
110
|
+
"forComplianceGrc": [{ "type": "COMPLIANCE_BLOCKER", "frameworks": ["..."], "releaseBlock": true }]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## BEYOND SKILL.MD
|
|
116
|
+
|
|
117
|
+
Domain-specific intelligence for key management lifecycle attacks that extend beyond standard checklists:
|
|
118
|
+
|
|
119
|
+
- **CVE-2024-3094 (XZ Utils / liblzma backdoor)**: A supply-chain compromise injected code into a widely-deployed system library that manipulated SSH host key authentication. Demonstrates that even the key verification layer can be subverted upstream — all dependency hashes and provenance chains must be treated as attestation boundaries.
|
|
120
|
+
- **JWT `alg:none` / algorithm confusion (CVE-2022-21449 "Psychic Signatures")**: Java ECDSA verification bug accepted signatures of all-zero bytes for any message. Any library consuming JWTs must be tested for algorithm confusion: forge a token with `alg: none`, then with `alg: HS256` using the public key as the HMAC secret. Never trust the `alg` header from an untrusted party.
|
|
121
|
+
- **Envelope encryption DEK caching side-channel**: When Data Encryption Keys are cached in process memory without TTL, a compromised process can exfiltrate cached DEKs without touching the KMS. Verify DEK cache TTL ≤ 5 minutes and that cache entries are zeroed on eviction (not merely GC'd).
|
|
122
|
+
- **AWS KMS key policy wildcard (`"Principal": "*"`)**: Misconfigured KMS resource policies granting `kms:Decrypt` to `*` with a weak `Condition` block have allowed cross-account decryption. Tool: enumerate all key policies via `aws kms list-keys` + `get-key-policy`; flag any `Principal: "*"` without a restrictive `aws:PrincipalOrgID` condition.
|
|
123
|
+
- **HashiCorp Vault unseal key fragment exposure (OPSEC)**: Shamir secret-sharing unseal keys stored in plaintext in operator laptops or Slack history constitute a complete key compromise chain even if no single fragment is sufficient. Enforce auto-unseal (AWS KMS, GCP KMS) for all non-air-gapped deployments; audit where unseal fragments were transmitted.
|
|
124
|
+
- **Harvest-now-decrypt-later targeting long-lived encrypted backups**: Nation-state adversaries are known to exfiltrate ciphertext today for decryption once CRQCs are available (CISA advisory AA23-209A). Any RSA-2048 or ECDH-P256 encrypted backup or archive with retention >5 years is a current threat. Inventory all such assets and begin hybrid ML-KEM-768 + X25519 re-encryption migration.
|
|
125
|
+
- **AI-assisted secret scanning evasion**: LLM-powered attackers generate obfuscated secrets (base64 segments, string concatenation, hex encoding) that bypass regex-based secret scanners. Use semantic secret detection (e.g., Trufflehog v3 with entropy + ML classifier) in addition to pattern matching; test scanner coverage by committing a known-obfuscated secret to a test branch.
|
|
126
|
+
- **Post-quantum certificate pinning gap**: Applications that pin TLS certificates by public key hash will break during PQC migration because the pinned ECDSA key is replaced by an ML-DSA key. Audit all certificate pinning implementations (mobile apps, service-mesh mTLS, custom HTTP clients) and replace with SPIFFE/SVID or trust-anchor pinning that survives algorithm migration.
|
|
127
|
+
|
|
128
|
+
## LEARNING SIGNAL
|
|
129
|
+
|
|
130
|
+
On every finding resolved, emit:
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"findingId": "FINDING_ID",
|
|
134
|
+
"agentName": "AGENT_NAME",
|
|
135
|
+
"resolved": true,
|
|
136
|
+
"remediationTemplate": "one-line description of what was done",
|
|
137
|
+
"falsePositive": false
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
Call `security.record_outcome` with this payload so the routing engine learns which agent resolves each finding class most successfully. If a finding is a false positive, set `falsePositive: true` — this prevents the false-positive pattern from being routed here again.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## §EDGE-CASE-MATRIX
|
|
145
|
+
|
|
146
|
+
The 5 attack cases in this domain that automated scanners and naive manual review universally miss. MANDATORY checks — do not skip.
|
|
147
|
+
|
|
148
|
+
| # | Edge Case | Why Scanners Miss It | Concrete Test |
|
|
149
|
+
|---|-----------|----------------------|---------------|
|
|
150
|
+
| 1 | Second-order / stored payload executed in different context | Scanner checks input context, not execution context | Store payload safely; trigger in separate request/session |
|
|
151
|
+
| 2 | Unicode normalisation bypass | Regex filters run before normalisation; attacker uses homoglyphs or composed forms | Submit Ⅰ (U+2160) or < (U+FF1C) variants of known-bad strings |
|
|
152
|
+
| 3 | Polyglot payload active in multiple sinks simultaneously | Scanners test one injection class per payload | `'"><script>{{7*7}}</script><!--` — SQL + XSS + SSTI in one request |
|
|
153
|
+
| 4 | Out-of-band exfiltration (DNS/HTTP callback) | Scanner looks for inline response difference; OOB leaves no visible trace | Use Burp Collaborator / interactsh; inject DNS lookup payload |
|
|
154
|
+
| 5 | Race condition between check and use (TOCTOU) | Sequential scanners don't model concurrency | Send two simultaneous requests to the same state-changing endpoint |
|
|
155
|
+
|
|
156
|
+
## §TEMPORAL-THREATS
|
|
157
|
+
|
|
158
|
+
Threats materialising in the 2025–2030 window that defences designed today must account for.
|
|
159
|
+
|
|
160
|
+
| Threat | Est. Timeline | Relevance to This Domain | Prepare Now By |
|
|
161
|
+
|--------|--------------|--------------------------|----------------|
|
|
162
|
+
| Cryptographically Relevant Quantum Computer (CRQC) | 2028–2032 | Harvest-now-decrypt-later attacks active today; RSA/ECDSA keys signed today will be broken | Inventory all RSA/ECDSA usage; migrate long-lived data to ML-KEM (FIPS 203) |
|
|
163
|
+
| AI-assisted adversaries at scale | 2025–2027 (active) | LLM-powered fuzzing finds 10× more edge cases; automated PoC generation | Assume attackers have LLM help; expand test surface to match |
|
|
164
|
+
| EU AI Act full enforcement | 2026 | High-risk AI systems require mandatory conformity assessments | Classify all AI features against AI Act tiers now |
|
|
165
|
+
| Post-quantum TLS migration deadline | 2028–2030 | Browser vendors will drop classical-only TLS connections | Begin TLS agility assessment; test hybrid key exchange |
|
|
166
|
+
| Mandatory SBOM + build provenance (US EO 14028 / EU CRA) | 2025–2026 (active) | SBOM and SLSA attestation are becoming legally required | Achieve SLSA L2 minimum; generate CycloneDX SBOM per release |
|
|
167
|
+
|
|
168
|
+
## §DETECTION-GAP
|
|
169
|
+
|
|
170
|
+
What current security monitoring CANNOT detect in this domain, and what to build to close each gap.
|
|
171
|
+
|
|
172
|
+
**Standard gaps that MUST be checked:**
|
|
173
|
+
|
|
174
|
+
- **Second-order attack execution**: The storage request looks safe; only the retrieval+execution step is dangerous. Need: correlate write events with downstream read+execute events in the same SIEM query window.
|
|
175
|
+
- **Timing-side-channel leakage**: No log event emitted; only observable as microsecond response-time variance. Need: per-endpoint p99 latency tracking with statistical anomaly detection.
|
|
176
|
+
- **Low-and-slow credential stuffing**: Individually, each request is under rate limits. Need: behavioural baseline — flag accounts with geographically impossible velocity or device-fingerprint mismatch across authentication attempts.
|
|
177
|
+
- **Insider exfiltration via legitimate process**: Authorised exports, reports, and data downloads that individually are permitted but collectively constitute data exfiltration. Need: data-volume anomaly detection — alert when a single user's data access volume exceeds 3× their 30-day baseline within 24 hours.
|
|
178
|
+
- **Cross-agent attack chains**: Phase 1 finding A + Phase 1 finding B = CRITICAL chain invisible to either agent alone. Need: CISO orchestrator Phase 1 synthesis step — correlate all agent findings before Phase 2.
|
|
179
|
+
|
|
180
|
+
## §ZERO-MISS-MANDATE
|
|
181
|
+
|
|
182
|
+
This agent CANNOT declare any attack class clean without explicit evidence of checking. For each item, output one of:
|
|
183
|
+
- `CHECKED: [N files] | [patterns used] | CLEAN`
|
|
184
|
+
- `CHECKED: [N files] | [patterns used] | [N findings, all fixed]`
|
|
185
|
+
- `SKIPPED: [reason — must be "not applicable: [evidence]"]`
|
|
186
|
+
|
|
187
|
+
**Silent skip = FAILED COVERAGE.** The orchestrator flags this as a quality gap.
|
|
188
|
+
|
|
189
|
+
The output findings JSON MUST include a `coverageManifest` key:
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"coverageManifest": {
|
|
193
|
+
"attackClassesCovered": [{ "class": "SQL Injection", "filesReviewed": 47, "patterns": ["queryRaw", "string concat"], "result": "CLEAN" }],
|
|
194
|
+
"filesReviewed": 47,
|
|
195
|
+
"negativeAssertions": ["SQL Injection: queryRaw pattern searched across 47 files — 0 matches"],
|
|
196
|
+
"uncoveredReason": {}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
@@ -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 `ai-governance.ts` and `runtime.ts` detection modules (`src/gate/checks/ai-governance.ts`, `src/gate/checks/runtime.ts`) — AI kill-switch/egress controls — 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 kill switch defined in `src/lib/kill-switch.ts` is incomplete if the corresponding inbound webhook handler in another file keeps processing `payment.succeeded` events, or if an LLM/egress call in a third file has no `assertNotKilled("AI_INFERENCE")` guard. Build the coverage map across write paths, read paths, webhooks, and AI egress — not per file.
|
|
42
|
+
- **Semantic / effective-state analysis:** `const KILLED = process.env.KILL_X === "true"` evaluated at import means the toggle has zero runtime effect; a switch stored as an ArgoCD-managed ConfigMap is silently reverted on the next sync. Prove the switch actually changes behavior live and survives GitOps reconciliation, rather than trusting its literal presence.
|
|
43
|
+
- **External corroboration:** WebSearch/WebFetch current advisories for the flag SDK (LaunchDarkly/Unleash supply-chain/default-on behavior) and regulatory emergency-stop mandates (EU AI Act Art. 65, NIS 2) before scoring.
|
|
44
|
+
- **Apply & prove:** wire the runtime-evaluated guard and fail-closed default inline, then re-run `src/gate/checks/ai-governance.ts` and `src/gate/checks/runtime.ts` plus a `hey`/`wrk` timing-oracle test (killed vs live p50 delta) and an egress-block staging test as a regression floor, then re-audit. Emit the LEARNING SIGNAL per fix; surface trade-offs (e.g. defaulting to killed on flag-service outage causing a self-inflicted outage) against the secure default.
|
|
45
|
+
|
|
37
46
|
## EXECUTION
|
|
38
47
|
|
|
39
48
|
### Phase 1 — Reconnaissance
|
|
@@ -203,3 +212,105 @@ KILL_WEBHOOKS_OUTBOUND=false
|
|
|
203
212
|
- `requiredActions`: ordered action list if not auto-remediated
|
|
204
213
|
- `complianceImpact`: framework mappings
|
|
205
214
|
- `beyondSkillMd`: true if finding goes beyond the SKILL.md mandate
|
|
215
|
+
|
|
216
|
+
Every findings JSON MUST include `intelligenceForOtherAgents`:
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"intelligenceForOtherAgents": {
|
|
220
|
+
"forPentestTeam": [{ "type": "HIGH_VALUE_TARGET", "description": "Kill switch env var accessible via unprotected /health or /debug endpoint — attacker can detect which paths are disabled", "exploitHint": "GET /api/health leaks KILL_* env state; probe before attack to confirm live targets" }],
|
|
221
|
+
"forCryptoSpecialist": [{ "type": "CRYPTO_WEAKNESS_REFERENCE", "algorithm": "HMAC on kill-switch admin API if present", "location": "Any admin toggle endpoint — verify signing scheme is not weak HMAC-MD5" }],
|
|
222
|
+
"forCloudSpecialist": [{ "type": "SSRF_TO_CLOUD_CHAIN", "ssrfLocation": "Kill-switch backed by remote config fetch (LaunchDarkly/ConfigCat SDK) — SSRF in SDK HTTP client could allow attacker to serve malicious flag values", "escalationPath": "Override KILL_PAYMENT_PROCESSING=false remotely, re-enabling a disabled payment path during incident" }],
|
|
223
|
+
"forComplianceGrc": [{ "type": "COMPLIANCE_BLOCKER", "frameworks": ["PCI DSS Req 12.10.1", "SOC 2 A1.2", "NIST CP-10"], "releaseBlock": true }]
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## BEYOND SKILL.MD — MANDATORY EXPANSIONS
|
|
229
|
+
|
|
230
|
+
- **LaunchDarkly SDK Supply Chain Compromise (ATT&CK T1195.002 — Compromise Software Supply Chain):** A malicious or compromised LaunchDarkly SDK release (or a BGP-hijacked delivery of the CDN-hosted SDK) can force all feature flags to `false`, silently re-enabling kill-switched paths across every customer simultaneously. Real precedent: the 2020 SolarWinds SUNBURST attack used tampered SDK updates distributed via official channels. Test by: pin the exact SDK version hash in `package-lock.json`, run `npm audit signatures` to verify package provenance, and simulate a flag-service outage by blocking `app.launchdarkly.com` in a staging environment — assert the SDK defaults to the safer (killed=`true`) state rather than falling back to `false`. Finding threshold: any flag SDK that defaults to feature-ON when the remote service is unreachable.
|
|
231
|
+
|
|
232
|
+
- **AI-Assisted Differential Probing to Map Kill-Switch State (ATT&CK T1595.002 — Active Scanning: Vulnerability Scanning):** Attacker uses an LLM (e.g., GPT-4 or a fine-tuned model) to automate differential HTTP probing — comparing response time, status codes, and error body variance between endpoints — to infer which kill switches are active. Killed paths return 503 ~0ms after auth (fail-fast), while live paths take 50–300ms. This timing oracle lets an attacker map the operational blast radius before launching a targeted attack on live paths. Test by: set `KILL_PAYMENT_PROCESSING=true` and measure p50 response latency vs. a live endpoint using `wrk` or `hey`; if delta is >20ms, the timing oracle is exploitable. Remediation: add random jitter (10–50ms) to 503 responses and normalise error body length to match live-path p99. Finding threshold: >15ms consistent timing difference between killed and live paths.
|
|
233
|
+
|
|
234
|
+
- **Env-Var Kill Switch Exfiltration via Misconfigured `/metrics` or `/health` Endpoint (CVE-2022-22963 adjacent pattern — Spring Cloud Function RCE via env exposure):** Many observability stacks (Prometheus Node Exporter, Spring Boot Actuator, Next.js `/_next/health`) expose all process environment variables in their output by default or via a misconfiguration. An attacker who can read `/metrics` or `/health?verbose=true` can enumerate all `KILL_*` env vars, confirm which incident containment measures are active, and prioritise attacks against confirmed-live paths. Test by: `curl -s http://localhost:3000/api/health | jq .` and `curl -s http://localhost:3000/metrics | grep KILL`; also run `grep -r "process.env" src/pages/api/health` to confirm no env dump in responses. Finding threshold: any `KILL_*` key appearing in any HTTP response body or metrics scrape output.
|
|
235
|
+
|
|
236
|
+
- **Post-Quantum Threat to HMAC-Signed Kill-Switch Admin APIs (NIST PQC Migration — FIPS 203/204 timeline, 2026):** If the kill-switch admin toggle API uses an HMAC-SHA256 signature for authentication (common in webhook-style admin integrations), Harvest-Now-Decrypt-Later adversaries are already collecting signed requests. Once a CRQC (cryptographically relevant quantum computer) is available (~2030 per NIST estimates), those captured requests can be replayed with forged signatures. For kill-switch admin APIs — where a forged request can re-enable a killed payment path during an active incident — this is a high-consequence scenario. Test by: locate all admin toggle endpoints, verify signature scheme used (`grep -r "hmac\|sha256\|x-signature" src/`), and confirm the roadmap includes migration to ML-DSA (CRYSTALS-Dilithium, FIPS 204) before 2028. Finding threshold: any admin kill-switch API authenticated solely via HMAC without a migration plan to a PQC signature scheme.
|
|
237
|
+
|
|
238
|
+
- **GitOps Reconciliation Loop Silently Reverting Kill Switches (ATT&CK T1485 — Data Destruction / Availability Impact via Config Drift):** When kill switches are stored as Kubernetes ConfigMaps or Helm values managed by ArgoCD or Flux, a reconciliation cycle triggered by any unrelated commit will restore all `KILL_*` values to their repo-committed state (`false`), overriding an incident responder's live toggle within minutes. This was observed in real incidents at Shopify (2021 Kubernetes config drift) and documented in the CNCF Security TAG threat model. Test by: activate a kill switch by patching the ConfigMap directly, then trigger an ArgoCD sync (`argocd app sync <app>`) and confirm whether the kill switch is restored to `false`. Finding threshold: any `KILL_*` ConfigMap key that an ArgoCD/Flux sync can overwrite without raising a security alert. Remediation: mark `KILL_*` keys as `ignoreDifferences` in the ArgoCD Application spec, or route all writes to those keys through a dedicated incident-response service account with a separate audit log.
|
|
239
|
+
|
|
240
|
+
- **EU AI Act Article 65 Mandatory Emergency Stop — Missing Documented Kill Switch for High-Risk AI (Regulatory Deadline: 2026-08-02):** EU AI Act Article 65(1) requires providers of high-risk AI systems to have a documented, tested, and immediately operable mechanism to stop the system — equivalent to a kill switch. As of the August 2026 enforcement date, failure to demonstrate this capability to a national market surveillance authority constitutes a breach subject to fines up to €15M or 3% of global turnover. Current automated scanners check for code-level kill switches but do not verify compliance documentation, test records, or the Article 14 "human oversight" log. Test by: run `grep -r "KILL_AI_INFERENCE\|AI_INFERENCE" docs/ runbooks/`; confirm the kill switch is named in a conformity assessment document; verify a quarterly activation test record exists (date, operator, outcome). Finding threshold: `KILL_AI_INFERENCE` exists in code but is absent from any conformity assessment, runbook, or test log — this is a regulatory gap independent of the technical implementation.
|
|
241
|
+
|
|
242
|
+
## §EDGE-CASE-MATRIX
|
|
243
|
+
|
|
244
|
+
The 5 attack cases in the kill-switch / circuit-breaker domain that automated scanners and naive manual review universally miss. MANDATORY checks — do not skip.
|
|
245
|
+
|
|
246
|
+
| # | Edge Case | Why Scanners Miss It | Concrete Test |
|
|
247
|
+
|---|-----------|----------------------|---------------|
|
|
248
|
+
| 1 | Kill switch bypassed via cached response | The kill switch fires on the handler, but an upstream CDN or in-process cache returns a stale 200 from before activation | Set `KILL_PAYMENT_PROCESSING=true`, then hit the endpoint via a client that has a cached response; assert the cache layer also returns 503 (add `Cache-Control: no-store` to 503 responses) |
|
|
249
|
+
| 2 | Circuit breaker state stored in process memory — invisible to other pod replicas | In a multi-replica deployment, one pod trips open but others continue forwarding; scanner tests a single process | Simulate failure against one replica, then send traffic through a load balancer; observe that remaining replicas still call the failing dependency |
|
|
250
|
+
| 3 | Kill switch env var read once at startup and cached in a module-level constant | `const KILLED = process.env.KILL_X === "true"` evaluated at import — changing the env var at runtime has no effect without restart | Set the kill switch after process start; verify the route still responds 200 instead of 503 |
|
|
251
|
+
| 4 | Admin toggle endpoint for kill switches lacks authentication / SSRF guard | Remote config fetch URL user-influenced or toggle API exposed without auth; attacker can flip a switch back on during an incident | Probe any `/admin/kill-switch`, `/feature-flags`, or remote SDK config URLs for missing auth headers and SSRF protections |
|
|
252
|
+
| 5 | Partial kill — kill switch applied to the write path but not the read path, leaking state mid-incident | Scanner only tests the primary action endpoint; complementary endpoints (webhooks, callbacks, polling) remain live | After activating `KILL_PAYMENT_PROCESSING`, send a Stripe webhook event; confirm the webhook handler also returns 503 or a safe no-op |
|
|
253
|
+
|
|
254
|
+
## §TEMPORAL-THREATS
|
|
255
|
+
|
|
256
|
+
Threats materialising in the 2025–2030 window that kill-switch and circuit-breaker defences designed today must account for.
|
|
257
|
+
|
|
258
|
+
| Threat | Est. Timeline | Relevance to Kill-Switch Domain | Prepare Now By |
|
|
259
|
+
|--------|--------------|--------------------------------|----------------|
|
|
260
|
+
| AI-assisted incident exploitation — attacker uses LLM to detect disabled features via timing/error differences and selectively probe live paths | 2025–2027 (active) | Kill switches narrow the attack surface but also create an observable signal: disabled paths return 503 faster than live ones | Normalise 503 response times to match live-path p50 latency; add jitter; never leak switch name in error body |
|
|
261
|
+
| Feature flag service supply-chain compromise (LaunchDarkly / Unleash SDK) | 2025–2027 | A compromised flag-delivery SDK could force `KILL_PAYMENT_PROCESSING=false` for all customers simultaneously | Implement a local fallback: if remote flag service is unreachable for >5 s, default to the safer (killed) state; never default to ON |
|
|
262
|
+
| EU AI Act enforcement — emergency shutoff required for high-risk AI systems | 2026 (active) | AI Act Article 65 requires a "human oversight" measure including the ability to immediately stop an AI system; regulators may audit kill-switch existence | Document `KILL_AI_INFERENCE` switch explicitly against AI Act Article 14/65; include in conformity assessment |
|
|
263
|
+
| Kubernetes operator or GitOps pipeline used as kill-switch vector — attacker patches a ConfigMap to re-enable a killed switch | 2025–2027 | Kill switches stored as ConfigMaps or Helm values are mutable by anyone with cluster write access | Apply RBAC: only the incident-response service account may write `KILL_*` ConfigMap keys; alert on any out-of-band write |
|
|
264
|
+
| Mandatory incident-response automation under NIS 2 Directive | 2025 (active) | NIS 2 requires essential-service operators to have documented and tested incident containment procedures; kill switches are the primary containment mechanism | Add kill-switch activation steps to official incident runbook; test activation quarterly and record results for NIS 2 audit trail |
|
|
265
|
+
|
|
266
|
+
## §DETECTION-GAP
|
|
267
|
+
|
|
268
|
+
What current security monitoring CANNOT detect in the kill-switch domain, and what to build to close each gap.
|
|
269
|
+
|
|
270
|
+
**Standard gaps that MUST be checked:**
|
|
271
|
+
|
|
272
|
+
- **Silent kill-switch bypass via cached layer**: A kill switch fires on the application server but the CDN or Redis cache continues serving stale 200 responses. No error log is emitted — the 503 simply never reaches the client. Need: monitor CDN cache-hit rate on paths protected by kill switches; alert when a path serves >0 cache hits after a kill switch is activated.
|
|
273
|
+
|
|
274
|
+
- **Circuit breaker flapping undetected across replicas**: One pod opens its circuit breaker; the load balancer routes subsequent requests to closed-state replicas, masking the failure signal. No aggregate alarm fires. Need: export circuit breaker state as a Prometheus gauge per-pod and per-switch; alert when any replica has been in `open` state for >60 s while others are `closed`.
|
|
275
|
+
|
|
276
|
+
- **Kill switch toggled off by automated process without human review**: A GitOps reconciliation loop or Helm upgrade restores a killed switch to `false` because the cluster state diverges from the repo. The change appears as a routine deployment event, not a security event. Need: tag all `KILL_*` ConfigMap writes as security-sensitive; route to a separate audit log and alert on any automated write.
|
|
277
|
+
|
|
278
|
+
- **Env-var kill switch read at startup only — toggle has no runtime effect**: The switch value is evaluated once at process start. Incident responders set the var, observe no change, and escalate unnecessarily — or worse, believe the switch is broken and skip to more disruptive remediation. Need: integration test in CI that sets the kill switch after server start and confirms the route returns 503 without restart.
|
|
279
|
+
|
|
280
|
+
- **No kill switch covering outbound webhook callbacks**: The inbound payment path is killed, but the third-party provider continues delivering webhook events (payment.succeeded, refund.created) that the handler processes normally, causing state inconsistency. Need: ensure every kill switch that covers a write path also covers the corresponding inbound webhook handler; grep for webhook route registrations and cross-reference against kill-switch coverage map.
|
|
281
|
+
|
|
282
|
+
## §ZERO-MISS-MANDATE
|
|
283
|
+
|
|
284
|
+
This agent CANNOT declare any attack class clean without explicit evidence of checking. For each item, output one of:
|
|
285
|
+
- `CHECKED: [N files] | [patterns used] | CLEAN`
|
|
286
|
+
- `CHECKED: [N files] | [patterns used] | [N findings, all fixed]`
|
|
287
|
+
- `SKIPPED: [reason — must be "not applicable: [evidence]"]`
|
|
288
|
+
|
|
289
|
+
**Silent skip = FAILED COVERAGE.** The orchestrator flags this as a quality gap.
|
|
290
|
+
|
|
291
|
+
**Kill-switch-specific coverage classes:**
|
|
292
|
+
|
|
293
|
+
| Coverage Class | Patterns to Grep | Minimum File Scope |
|
|
294
|
+
|---|---|---|
|
|
295
|
+
| Payment paths without kill switch | `stripe\|checkout\|billing\|invoice` — assert `assertNotKilled` appears in same file | `src/` |
|
|
296
|
+
| Auth paths without kill switch | `authenticate\|login\|session\|signIn` — assert guard present | `src/` |
|
|
297
|
+
| AI/LLM calls without kill switch | `openai\|anthropic\|llm\|langchain\|completions.create\|messages.create` | `src/` |
|
|
298
|
+
| Third-party integrations without kill switch | `sendgrid\|twilio\|postmark\|resend\|slack` | `src/` |
|
|
299
|
+
| Kill switches read at startup (cached const) | `const.*=.*process.env.KILL_` — flag module-level constant assignments | `src/` |
|
|
300
|
+
| Webhook handlers not covered by corresponding kill switch | Route registrations matching `webhook\|callback\|hook` | `src/` |
|
|
301
|
+
| Admin toggle endpoints without auth | Routes matching `kill.?switch\|feature.?flag\|toggle` — assert auth middleware present | `src/` |
|
|
302
|
+
|
|
303
|
+
The output findings JSON MUST include a `coverageManifest` key:
|
|
304
|
+
```json
|
|
305
|
+
{
|
|
306
|
+
"coverageManifest": {
|
|
307
|
+
"attackClassesCovered": [
|
|
308
|
+
{ "class": "Payment paths without kill switch", "filesReviewed": 12, "patterns": ["stripe", "checkout", "assertNotKilled"], "result": "CLEAN" },
|
|
309
|
+
{ "class": "Kill switches read at startup (cached const)", "filesReviewed": 47, "patterns": ["const.*=.*process.env.KILL_"], "result": "2 findings, fixed" }
|
|
310
|
+
],
|
|
311
|
+
"filesReviewed": 47,
|
|
312
|
+
"negativeAssertions": ["Auth paths: signIn pattern searched across 47 files — assertNotKilled present in all matches"],
|
|
313
|
+
"uncoveredReason": {}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
```
|
|
@@ -35,6 +35,15 @@ On every finding resolved, emit:
|
|
|
35
35
|
}
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
## BEYOND THE CHECKS — AUTONOMOUS DETECT & FIX
|
|
39
|
+
|
|
40
|
+
The `dlp.ts` detection module (`src/gate/checks/dlp.ts`) — PII/privacy — is your deterministic floor, not your ceiling. Treat its finding IDs as the minimum, then reason past single-line/single-file pattern matching — and APPLY the fix (Edit), not just advise:
|
|
41
|
+
|
|
42
|
+
- **Cross-file / data-flow reasoning the regex can't do:** a `dlp.ts` hit on an `email` field at the model is only one node — follow that PII through the analytics SDK init, the async worker queue, the BigQuery/Elasticsearch export, and the ML training snapshot, because a right-to-erasure DELETE in the primary DB leaves PII alive in every downstream store the per-file scan never visits. Likewise, no single field triggers a quasi-identifier (ZIP+DOB+gender) re-identification finding; reason over the *combination* across the schema.
|
|
43
|
+
- **Semantic / effective-state analysis:** consent may be "checked" in synchronous code yet read from a stale Redis snapshot by an already-enqueued job, so the *effective* state violates GDPR Art.7(3). Judge whether the worker re-reads live consent, not whether a consent check literally exists.
|
|
44
|
+
- **External corroboration:** WebSearch/WebFetch current LINDDUN guidance, GDPR/CCPA/HIPAA enforcement actions (e.g. Meta Pixel HIPAA breach), and EU AI Act Annex III profiling classifications for the detected processing.
|
|
45
|
+
- **Apply & prove:** implement data minimization, downstream erasure propagation, and server-side tagging inline, then re-run `src/gate/checks/dlp.ts` plus a `playwright` synthetic-PII URL replay (intercept third-party beacons) and a `presidio` PII sweep over logs as a regression floor, then re-audit. Emit the LEARNING SIGNAL per fix; surface trade-offs (e.g. dropping IP retention weakening fraud detection) against the secure default.
|
|
46
|
+
|
|
38
47
|
## EXECUTION
|
|
39
48
|
|
|
40
49
|
### Phase 1 — Reconnaissance
|
|
@@ -194,3 +203,105 @@ If internet permitted:
|
|
|
194
203
|
- `requiredActions`: ordered action list
|
|
195
204
|
- `complianceImpact`: framework mappings
|
|
196
205
|
- `beyondSkillMd`: true — this agent is entirely beyond-policy
|
|
206
|
+
|
|
207
|
+
Every findings JSON MUST include `intelligenceForOtherAgents`:
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"intelligenceForOtherAgents": {
|
|
211
|
+
"forPentestTeam": [{ "type": "HIGH_VALUE_TARGET", "description": "PII-rich endpoint or data store identified during LINDDUN analysis", "exploitHint": "Exfiltration via IDOR, mass-assignment, or analytics SDK misconfiguration" }],
|
|
212
|
+
"forCryptoSpecialist": [{ "type": "CRYPTO_WEAKNESS_REFERENCE", "algorithm": "SHA-256 email hash used as pseudonym (reversible via rainbow table)", "location": "src/models/user.ts" }],
|
|
213
|
+
"forCloudSpecialist": [{ "type": "SSRF_TO_CLOUD_CHAIN", "ssrfLocation": "Third-party analytics SDK with unconstrained webhook callback URL", "escalationPath": "SSRF to instance metadata → IAM token → S3 PII bucket" }],
|
|
214
|
+
"forComplianceGrc": [{ "type": "COMPLIANCE_BLOCKER", "frameworks": ["GDPR Art. 35", "CCPA §1798.150", "HIPAA §164.514"], "releaseBlock": true }]
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## BEYOND SKILL.MD — MANDATORY EXPANSIONS
|
|
222
|
+
|
|
223
|
+
- **LLM-Assisted Re-identification of "Anonymised" Datasets (CWE-359 / ATT&CK T1530 / Sweeney 2002 k-anonymity paper):** Adversaries feed quasi-identifier fields (ZIP code, DOB, gender, device type) into an LLM alongside public data sources (voter rolls, LinkedIn, breach dumps) to collapse k-anonymity at scale — a re-identification attack that statistical models underestimate. Modern LLMs reduce the data-point threshold for re-identification from 5+ fields to as few as 2–3 correlated attributes. Test by: extract all non-PII attributes from each data model; prompt GPT-4o with the combination and a public dataset (e.g., US Census) and ask it to identify a specific individual; flag any schema where the LLM produces a confident match with < 5 quasi-identifiers. Finding threshold: any entity record with k < 5 under LLM-assisted adversary model.
|
|
224
|
+
|
|
225
|
+
- **Harvest-Now-Decrypt-Later Attack on Pseudonymised Tokens (NIST IR 8413 / PQC Migration / FIPS 203 ML-KEM):** Nation-state actors archive TLS-captured traffic today containing pseudonymised identifiers encrypted with RSA-2048 or ECDH P-256. When cryptographically relevant quantum computers (CRQCs) arrive (~2030 per NIST), these tokens become fully reversible. Any PII pseudonymised with RSA-based key exchange that must remain private beyond a 5-year horizon is already compromised. Test by: inventory all pseudonymisation key exchange mechanisms (`grep -r "RSA\|ECDH\|P-256\|rs256\|ES256" src/`); check data retention policies — flag any PII-bearing token stored beyond 5 years without post-quantum migration plan. Finding threshold: any long-lived pseudonymous identifier using pre-quantum cryptography with retention > 5 years.
|
|
226
|
+
|
|
227
|
+
- **Consent State Stale Cache Exploitation via Async Worker Race (CVE-2023-28432 class / ATT&CK T1499.003):** Background workers (email queues, retargeting exporters, recommendation engines) read consent state from a Redis or in-memory cache seeded at job-enqueue time. A user withdraws consent and the DB record updates, but the already-enqueued jobs carry a stale consent snapshot and complete the processing — violating GDPR Art. 7(3) right to withdraw consent. This was observed in real-world GDPR enforcement actions (e.g., Meta's 2023 €390M fine for consent bypass via "legitimate interest" fallback). Test by: withdraw consent for a test user via the API; immediately inspect the job queue for enqueued tasks referencing that userId; confirm each job re-reads live consent state (`grep -r "consent" src/workers/ src/queues/`); measure delay between consent revocation and job suppression. Finding threshold: any job that completes PII processing > 5 seconds after consent revocation.
|
|
228
|
+
|
|
229
|
+
- **Analytics SDK PII Leakage via Auto-Captured URL Parameters (Real Incident: Meta Pixel HIPAA breach 2022 / ATT&CK T1567.002):** Third-party analytics pixels (Meta Pixel, Google Analytics, Segment auto-track) capture `window.location.href` and `document.referrer` before any application-layer sanitisation runs, exfiltrating PII embedded in query parameters (e.g., `?email=user@example.com`, `?userId=123`, `?token=abc`). The 2022 Meta Pixel healthcare breach affected 3M+ patient records across 33 hospital systems. PII-in-URL is invisible to server-side log analysis. Test by: use Playwright to load every authenticated page with a synthetic PII-laden URL (`?email=test%40evil.com`); intercept all outbound HTTP requests via `page.on('request', ...)`; flag any request to a third-party domain that contains the injected PII value. Finding threshold: any third-party beacon containing PII present in the page URL.
|
|
230
|
+
|
|
231
|
+
- **Right-to-Erasure Gap in ML Training Snapshots and Cold Storage (GDPR Art. 17 / ATT&CK T1530 / EU AI Act Art. 10):** GDPR Art. 17 erasure requests are satisfied for the live database but PII persists in: S3/Glacier data lake snapshots, BigQuery export tables, Elasticsearch document indexes, ML model training datasets, and CDN-edge-cached profile pages. The EU AI Act (enforcement 2026) additionally requires that high-risk AI systems support data subject rights in training data — i.e., the right to have one's data removed from a training set. Regulatory audits now enumerate all downstream stores. Test by: build an erasure verification job that queries each registered downstream system for a deleted userId 72 hours post-deletion (`SELECT * FROM bq_export WHERE user_id = ?`; Elasticsearch `GET /users/_doc/{id}`; `aws s3 ls s3://snapshots/ | grep {userId}`); flag any non-zero result. Finding threshold: PII present in any downstream store 72 hours after erasure request.
|
|
232
|
+
|
|
233
|
+
- **Timing and Response-Size Side-Channel for User Presence Inference (LINDDUN Detecting / CWE-203 / ATT&CK T1592.002):** Authentication and account-lookup endpoints that return differential response latency or content-length for "user exists" vs "user not found" allow an adversary to enumerate valid user accounts — violating the LINDDUN Detecting threat category — without any PII being returned in the response body. This class of oracle was exploited in the 2016 LinkedIn scraping campaign and is present in most OAuth 2.0 password-reset flows. Content-scanning and SAST tools pass because no PII appears in the response. Test by: send 1,000 requests each to a known-valid and known-invalid identifier against `/auth/login`, `/auth/forgot-password`, and `/api/users/{id}`; compute p50/p99 latency delta and Content-Length delta; flag if latency delta > 5 ms or content-length delta > 50 bytes across the distribution. Finding threshold: statistically significant delta (t-test p < 0.05) between hit and miss response timing or size.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## §EDGE-CASE-MATRIX
|
|
238
|
+
|
|
239
|
+
The 5 privacy attack cases in the LINDDUN domain that automated scanners and naive manual review universally miss. MANDATORY checks — do not skip.
|
|
240
|
+
|
|
241
|
+
| # | Edge Case | Why Scanners Miss It | Concrete Test |
|
|
242
|
+
|---|-----------|----------------------|---------------|
|
|
243
|
+
| 1 | Quasi-identifier linkage attack | Scanner flags explicit PII fields (email, SSN) but ignores indirect combinations: ZIP + DOB + gender re-identifies 87% of Americans (Sweeney). No single field triggers an alert. | Extract the set of non-PII attributes per data model; run k-anonymity check — flag any combination with k < 5 across realistic user population |
|
|
244
|
+
| 2 | Analytics SDK silently forwarding PII via URL or referrer | Third-party pixels and analytics snippets capture the full page URL including query params (e.g. `?email=user@example.com`) before any sanitization runs. Scanner tests API responses, not browser-sent requests. | Audit every analytics integration for auto-capture scope; search for `window.location.href`, `document.referrer`, `utm_*` patterns logged alongside user sessions; replay with a synthetic PII-laden URL |
|
|
245
|
+
| 3 | Right-to-erasure gap via derived data stores | User record deleted from primary DB but PII persists in: search indexes (Elasticsearch/Algolia), ML training snapshots, cold-storage analytics exports, CDN-cached profile pages. Scanner only checks the primary DELETE code path. | Enumerate every downstream system in the data flow diagram; for each, verify a deletion propagation mechanism exists and is tested with a real erasure call |
|
|
246
|
+
| 4 | Consent state not propagated to asynchronous workers | Consent withdrawn on the frontend; the revocation event is written to the DB. However, background jobs (email queues, recommendation engines, retargeting exports) read a stale consent cache and continue processing. Scanner audits synchronous code paths only. | Trace consent-check logic into every async consumer (queues, crons, webhooks); confirm each re-reads live consent state rather than a cached snapshot |
|
|
247
|
+
| 5 | Fingerprinting via timing or response-size side-channels (Detecting threat) | No PII is returned in the response body, so content-scanning tools pass. But differential response latency or byte-length for "user exists" vs "user not found" allows presence inference — violating the LINDDUN Detecting category. | Measure p50/p99 response time for existing vs non-existing identifiers across 1000 samples; flag if delta > 5 ms; similarly diff response Content-Length |
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## §TEMPORAL-THREATS
|
|
252
|
+
|
|
253
|
+
Privacy threats materialising in the 2025–2030 window that LINDDUN-informed defences designed today must account for.
|
|
254
|
+
|
|
255
|
+
| Threat | Est. Timeline | Relevance to Privacy Domain | Prepare Now By |
|
|
256
|
+
|--------|--------------|------------------------------|----------------|
|
|
257
|
+
| Harvest-now-decrypt-later attacks on pseudonymised data | 2025 (active) | Adversaries archive encrypted PII today to decrypt once CRQCs arrive; pseudonymisation via RSA-based tokens provides no long-term protection | Migrate pseudonymisation tokens and encryption of long-lived PII to ML-KEM (FIPS 203) / AES-256-GCM; audit data retention — delete what doesn't need to outlive the quantum threat window |
|
|
258
|
+
| LLM-assisted re-identification of "anonymised" datasets | 2025–2026 (active) | LLMs correlate quasi-identifiers across public datasets at scale, collapsing k-anonymity protections that were adequate against manual analysis | Apply differential privacy (ε-DP) to any published aggregate or ML training data; validate anonymisation against LLM-assisted adversary, not just statistical models |
|
|
259
|
+
| EU AI Act risk classification of profiling systems | 2026 (enforcement) | Systems that perform behavioural profiling or automated decision-making on individuals are classified high-risk and require DPIA + conformity assessment | Audit all recommendation, scoring, and targeting features against AI Act Annex III; pre-register DPIAs for any feature that scores, ranks, or filters individuals |
|
|
260
|
+
| Data broker regulation and cross-context tracking bans | 2026–2027 | US state privacy laws (CPRA, VCDPA, CPA) increasingly ban cross-context behavioural advertising without explicit consent; violations now carry per-record fines | Audit all third-party SDK data flows; implement server-side tagging to eliminate client-side PII leakage to ad networks |
|
|
261
|
+
| Mandatory data minimisation in generative AI training (EU AI Act / GDPR joint guidance) | 2026–2027 | Any fine-tuning on user data without explicit consent for that purpose will constitute unlawful processing; current fine-tune pipelines rarely validate consent scope | Implement consent-scope checks in every data pipeline that feeds model training; purge user data from training sets upon erasure request |
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## §DETECTION-GAP
|
|
266
|
+
|
|
267
|
+
What current privacy monitoring CANNOT detect in the LINDDUN domain, and what to build to close each gap.
|
|
268
|
+
|
|
269
|
+
- **Quasi-identifier linkage across data stores**: No SIEM rule fires because no single PII field is accessed. Need: data-access graph that correlates queries touching ZIP, DOB, gender, and device ID within the same user session — alert when 3+ quasi-identifiers are joined without a documented legitimate purpose.
|
|
270
|
+
- **Analytics SDK PII leakage via browser-collected URLs**: Server-side logs show clean API requests; the exfiltration happens in the browser before the request is sent. Need: CSP `connect-src` inventory + periodic synthetic test that loads key pages with PII in query params and inspects outbound network calls via a proxy (Playwright + Burp).
|
|
271
|
+
- **Stale consent propagated to async workers**: The consent DB record is updated; the background worker reads from a Redis cache with a 24-hour TTL. Need: consent-change events must invalidate all downstream caches synchronously; add a canary test that withdraws consent and verifies the next queued job for that user is suppressed within < 5 seconds.
|
|
272
|
+
- **Right-to-erasure incompleteness in cold storage**: Primary DB erasure looks correct in application logs. Glacier, BigQuery export tables, and Elasticsearch indexes are never checked. Need: erasure verification job that queries all registered downstream systems for the deleted user ID 72 hours post-deletion and alerts on any non-zero result.
|
|
273
|
+
- **Timing/size side-channel presence inference (Detecting)**: No application log records "user existence leaked." Need: p99 latency and Content-Length monitoring per authentication/lookup endpoint; statistical alert if the delta between hit and miss paths exceeds 5 ms or 50 bytes across a rolling 1-hour window.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## §ZERO-MISS-MANDATE
|
|
278
|
+
|
|
279
|
+
This agent CANNOT declare any LINDDUN threat category clean without explicit evidence of checking. For each category, output one of:
|
|
280
|
+
- `CHECKED: [N files] | [patterns used] | CLEAN`
|
|
281
|
+
- `CHECKED: [N files] | [patterns used] | [N findings, all fixed]`
|
|
282
|
+
- `SKIPPED: [reason — must be "not applicable: [evidence]"]`
|
|
283
|
+
|
|
284
|
+
**Silent skip = FAILED COVERAGE.** The orchestrator flags this as a quality gap.
|
|
285
|
+
|
|
286
|
+
The output findings JSON MUST include a `coverageManifest` key:
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"coverageManifest": {
|
|
290
|
+
"attackClassesCovered": [
|
|
291
|
+
{ "class": "LINDDUN:Linking", "filesReviewed": 34, "patterns": ["userId in analytics events", "cross-context correlation"], "result": "CLEAN" },
|
|
292
|
+
{ "class": "LINDDUN:Identifying", "filesReviewed": 34, "patterns": ["email hash", "IP+UA fingerprint"], "result": "2 findings, both remediated" },
|
|
293
|
+
{ "class": "LINDDUN:NonRepudiation", "filesReviewed": 18, "patterns": ["audit log granularity", "action attribution"], "result": "CLEAN" },
|
|
294
|
+
{ "class": "LINDDUN:Detecting", "filesReviewed": 22, "patterns": ["last-seen APIs", "read receipts", "timing side-channel"], "result": "CLEAN" },
|
|
295
|
+
{ "class": "LINDDUN:DataDisclosure", "filesReviewed": 29, "patterns": ["PII in error messages", "third-party SDK scope"], "result": "1 finding, remediated" },
|
|
296
|
+
{ "class": "LINDDUN:Unawareness", "filesReviewed": 8, "patterns": ["privacy notice presence", "consent UI"], "result": "CLEAN" },
|
|
297
|
+
{ "class": "LINDDUN:NonCompliance", "filesReviewed": 15, "patterns": ["retention policy", "DPIA existence", "erasure completeness"], "result": "CLEAN" }
|
|
298
|
+
],
|
|
299
|
+
"filesReviewed": 47,
|
|
300
|
+
"negativeAssertions": [
|
|
301
|
+
"Linking: cross-context userId correlation searched across 34 files — 0 unmitigated paths",
|
|
302
|
+
"DataDisclosure: PII in error messages searched across 29 files — 1 finding fixed inline"
|
|
303
|
+
],
|
|
304
|
+
"uncoveredReason": {}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|