security-mcp 1.1.2 → 1.1.4

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.
@@ -100,7 +100,19 @@ tool("security.start_review", "Start a stateful security review run, lock the sc
100
100
  headRef: headRef ?? "HEAD",
101
101
  requiredSteps: run.requiredSteps,
102
102
  operatingMandate: "90% fixing, 10% advisory. Write the fix. Implement the control. Enforce the policy. Do not list vulnerabilities and walk away.",
103
+ coverageProtocol: {
104
+ step0: "Enumerate ALL source files first → write .mcp/agent-runs/{runId}/coverage-manifest.json before any analysis",
105
+ step1: "Taint-trace every user-controlled input (req.body, req.query, event.data, etc.) to ALL sinks → write taint-map.json",
106
+ step2: "Negative assertion per attack class: 'ATTACK CLASS: {name} | FILES: {n}/{total} | PATTERNS: {list} | RESULT: CLEAN or N findings (N/N fixed)'",
107
+ step3: "Fix verification loop: re-run the triggering check after every fix — do NOT advance until VERIFIED CLEAN",
108
+ step4: "All HIGH/CRITICAL: FIXED with verified-clean re-run, OR formally blocked with risk-acceptance record + failing gate"
109
+ },
103
110
  nextSteps: [
111
+ "Step 0: Enumerate ALL source files → write coverage-manifest.json before any analysis begins.",
112
+ "Step 1: For every user-controlled input found, trace it to ALL sinks → write taint-map.json.",
113
+ "After every attack class reviewed: write NEGATIVE ASSERTION confirming files checked and result.",
114
+ "After every fix: re-run the triggering check and confirm CLEAN before proceeding to next finding.",
115
+ "All findings must be FIXED (verified-clean) or BLOCKED (risk-accepted + gate failing). No open HIGH/CRITICAL at completion.",
104
116
  "Run security.threat_model with this runId.",
105
117
  "Run security.checklist with this runId.",
106
118
  "Run security.run_pr_gate with this runId.",
@@ -361,22 +373,108 @@ Describe Level 0 (context) and Level 1 (process) flows in prose or embed a diagr
361
373
  |---|---|---|---|---|
362
374
  | TM-001 | | | | PENDING |
363
375
 
376
+ ## 4b. LINDDUN Privacy Threat Analysis
377
+
378
+ | Category | Description | Threat | Mitigation |
379
+ |---|---|---|---|
380
+ | Linking | Can records across contexts be linked? | | |
381
+ | Identifying | Can data be traced to an individual? | | |
382
+ | Non-repudiation | Can users deny their actions? | | |
383
+ | Detecting | Can sensitive behavior be inferred from metadata? | | |
384
+ | Data Disclosure | Can data be exposed beyond its intended scope? | | |
385
+ | Unawareness | Are users unaware of data collection? | | |
386
+ | Non-compliance | Does the system violate regulations? | | |
387
+
388
+ ## 4c. TRIKE Risk Matrix
389
+
390
+ | Actor | Action | Asset | Allowed? | Risk if Violated |
391
+ |---|---|---|---|---|
392
+ | Authenticated User | Read | Own profile | Yes | — |
393
+ | Authenticated User | Read | Other user profile | No | CRITICAL |
394
+ | Service Account | Write | Production DB | Restricted | HIGH |
395
+
396
+ ## 4d. DREAD Scoring
397
+
398
+ | Threat | Damage (0-10) | Reproducibility | Exploitability | Affected Users | Discoverability | Total |
399
+ |---|---|---|---|---|---|---|
400
+ | _Threat 1_ | | | | | | |
401
+
402
+ ## 4e. Attack Trees — Top 3 Critical Paths
403
+
404
+ **Goal 1: Achieve authentication bypass**
405
+ - OR: Exploit JWT algorithm confusion (requires: access to token + public key)
406
+ - AND: Obtain RS256 public key (from JWKS endpoint or source code)
407
+ - AND: Re-sign token as HS256 using public key as HMAC secret
408
+ - OR: Session fixation (requires: pre-auth request, no session regeneration)
409
+
410
+ **Goal 2: Exfiltrate PII/cardholder data**
411
+ - OR: IDOR via unvalidated object reference
412
+ - OR: SQLi / NoSQL injection in query endpoint
413
+ - OR: SSRF to internal data store
414
+
415
+ **Goal 3: Achieve remote code execution**
416
+ - OR: SSTI via template compilation from user input
417
+ - OR: Deserialization gadget chain (node-serialize / eval)
418
+ - OR: Prototype pollution → downstream exec sink
419
+
420
+ ## 5. Adversary Profiles
421
+
422
+ | Profile | Goal | ATT&CK Techniques | Test Focus |
423
+ |---|---|---|---|
424
+ | APT / Nation-State | Persistent access + exfiltration | T1195, T1078, T1027 | What steps produce NO log entries? |
425
+ | Ransomware Group | Encrypt backups, maximize leverage | T1490, T1485, T1496 | Can attacker reach and delete backups? |
426
+ | Insider (DevOps) | Exfiltration or sabotage with valid creds | T1213, T1087 | What can a DevOps engineer access they shouldn't? |
427
+ | Script Kiddie | Quick wins via automated tools | T1190, T1595 | Does WAF/rate limiting stop nuclei/sqlmap? |
428
+
429
+ ## 6. Supply Chain Threats
430
+
431
+ | Threat | Vector | Likelihood | Mitigation |
432
+ |---|---|---|---|
433
+ | Dependency confusion | Private pkg name registered on npm | | SHA-pin all deps; use npm audit |
434
+ | Typosquatting | Misspelled package installed | | Lock file + npm audit on CI |
435
+ | CI cache poisoning | Malicious action poisons build cache | | Pin actions to SHA; no cache cross-branches |
436
+ | Compromised upstream | Maintainer account takeover | | SBOM + Sigstore verification |
437
+ | Malicious maintainer | Legitimate maintainer inserts backdoor | | OpenSSF scorecard + CISA KEV monitoring |
438
+ | pwn-request | pull_request_target with head code | | Explicit head_ref check; no auto-use of forked code |
439
+
364
440
  ## 11. Pre-Release Checklist (Section 22E)
365
441
 
366
442
  - [ ] Threat model reviewed by security-designated reviewer
367
443
  - [ ] All SAST/SCA/IaC/container scan gates pass
368
444
  - [ ] Auth and authorization logic reviewed
369
- - [ ] Secrets handling reviewed - no hardcoded secrets
445
+ - [ ] Secrets handling reviewed no hardcoded secrets
370
446
  - [ ] Input validation present on all new inputs (server-side confirmed)
371
- - [ ] Error messages reviewed - no information leakage
372
- - [ ] Logging confirmed - required events logged, no PII in logs
447
+ - [ ] Error messages reviewed no information leakage
448
+ - [ ] Logging confirmed required events logged, no PII in logs
373
449
  - [ ] Security headers verified in staging
374
450
  - [ ] Rate limiting confirmed on all new endpoints
375
451
  - [ ] CORS configuration reviewed
376
452
  - [ ] Dependencies reviewed for new CVEs
377
- - [ ] Network rules reviewed - no 0.0.0.0/0, all traffic via private paths
453
+ - [ ] Network rules reviewed no 0.0.0.0/0, all traffic via private paths
378
454
  - [ ] IR playbook updated if new attack surface introduced
379
455
  - [ ] Compliance requirements addressed and documented
456
+
457
+ ## 12. Business Logic Abuse
458
+
459
+ | Workflow | State Machine Step | Can skip? | Invariant | Test |
460
+ |---|---|---|---|---|
461
+ | _e.g. Checkout_ | Cart → Payment → Confirm | Can step 2 be skipped? | Amount must match cart total | POST /confirm without /payment |
462
+ | _e.g. Subscription_ | Trial → Upgrade → Active | Can upgrade be replayed? | One upgrade per user | Concurrent PATCH /upgrade |
463
+
464
+ - [ ] Full state machine mapped for all significant workflows
465
+ - [ ] Step-skip tests designed and executed
466
+ - [ ] Negative value inputs tested on all numeric fields (quantity, price, balance, seats)
467
+ - [ ] Concurrent request tests executed for all limit-once invariants
468
+
469
+ ## 13. PoC Requirement
470
+
471
+ **Every HIGH or CRITICAL finding must have a working PoC before sign-off.**
472
+
473
+ | Finding ID | Severity | PoC Written | PoC Confirmed Working | Fix Written | Fix Verified Clean |
474
+ |---|---|---|---|---|---|
475
+ | | HIGH | [ ] | [ ] | [ ] | [ ] |
476
+
477
+ Rule: PoC must be written BEFORE the fix. After the fix, re-run the PoC and confirm it fails.
380
478
  `;
381
479
  if (runId) {
382
480
  await updateReviewStep(runId, "threat_model", "completed", {
@@ -402,80 +500,212 @@ Use before every production release. All items must be checked or explicitly ris
402
500
  ## All Surfaces
403
501
 
404
502
  - [ ] Threat model completed and reviewed by security-designated reviewer
405
- - [ ] SAST scan results reviewed - all CRITICAL/HIGH findings resolved
406
- - [ ] SCA scan - no CRITICAL CVEs in dependencies; HIGH CVEs triaged
407
- - [ ] Secrets scan clean (Trufflehog / Gitleaks)
408
- - [ ] IaC scan - no HIGH/CRITICAL misconfigurations (Checkov / tfsec)
409
- - [ ] Container scan - no CRITICAL CVEs with available fix (Trivy / Grype)
410
- - [ ] Error messages reviewed - no stack traces, schema details, or enum leakage
411
- - [ ] Logging reviewed - all required events logged; no PII, secrets, or tokens in logs
412
- - [ ] Dependencies reviewed for new CVEs introduced by this change
503
+ - [ ] SAST scan results reviewed all CRITICAL/HIGH findings resolved or risk-accepted with ticket
504
+ - [ ] SCA scan no CRITICAL CVEs in dependencies; HIGH CVEs triaged and scheduled
505
+ - [ ] Secrets scan clean (Trufflehog / Gitleaks) — no credentials, tokens, or keys in source
506
+ - [ ] IaC scan no HIGH/CRITICAL misconfigurations (Checkov / tfsec)
507
+ - [ ] Container scan no CRITICAL CVEs with available fix (Trivy / Grype)
413
508
  - [ ] SBOM generated for this release artifact
414
- - [ ] Rollback plan documented and tested
509
+ - [ ] SLSA provenance attestation generated for release artifacts
510
+ - [ ] Error messages reviewed — no stack traces, schema details, internal paths, or enum leakage
511
+ - [ ] Logging reviewed — all required events logged; no PII, secrets, or tokens in logs
512
+ - [ ] Dependencies reviewed for new CVEs introduced by this change
513
+ - [ ] CISA KEV cross-check completed for all dependency CVEs
514
+ - [ ] Rollback plan documented and tested (can revert within 15 minutes)
415
515
  - [ ] IR playbook updated if a new attack surface was introduced
516
+ - [ ] Regression gate: previous CRITICAL/HIGH findings verified still fixed
517
+ - [ ] Coverage-gap disclosure: documented what this scan CANNOT catch (business logic, runtime behavior)
416
518
 
417
519
  ## Web / Frontend
418
520
 
419
- - [ ] Content-Security-Policy header present with nonce-based script control (no unsafe-inline)
420
- - [ ] HSTS header with includeSubDomains and preload
421
- - [ ] X-Frame-Options: DENY
422
- - [ ] X-Content-Type-Options: nosniff
521
+ - [ ] Content-Security-Policy: nonce-based script control unsafe-inline and unsafe-eval absent
522
+ - [ ] Content-Security-Policy: default-src 'self' with explicit allowlists for external resources
523
+ - [ ] HSTS: max-age=31536000; includeSubDomains; preload
524
+ - [ ] X-Frame-Options: DENY (or SAMEORIGIN with justification)
525
+ - [ ] X-Content-Type-Options: nosniff on all responses including error pages
423
526
  - [ ] Referrer-Policy: strict-origin-when-cross-origin
424
- - [ ] Permissions-Policy set
425
- - [ ] No inline JavaScript or inline event handlers
426
- - [ ] Subresource Integrity (SRI) on any third-party scripts
427
- - [ ] CSRF protection on all state-changing endpoints
428
- - [ ] XSS: no dangerouslySetInnerHTML without sanitization
527
+ - [ ] Permissions-Policy: camera, microphone, geolocation restricted
528
+ - [ ] Cross-Origin-Opener-Policy (COOP): same-origin
529
+ - [ ] Cross-Origin-Embedder-Policy (COEP): require-corp where SharedArrayBuffer used
530
+ - [ ] Cross-Origin-Resource-Policy (CORP): same-origin or same-site on API responses
531
+ - [ ] Trusted Types policy enforced (require-trusted-types-for 'script') — DOM XSS sinks covered
532
+ - [ ] No inline JavaScript or inline event handlers (onclick, onload, onerror, etc.)
533
+ - [ ] No dangerouslySetInnerHTML without DOMPurify sanitization
534
+ - [ ] All user-supplied data escaped before rendering in server-side templates
535
+ - [ ] document.write(), innerHTML, insertAdjacentHTML, eval() DOM sink audit completed
536
+ - [ ] postMessage handlers validate event.origin against explicit allowlist
537
+ - [ ] Subresource Integrity (SRI) on all third-party scripts and stylesheets
538
+ - [ ] CSRF protection on all state-changing endpoints (SameSite + CSRF tokens)
539
+ - [ ] Open redirect prevention: redirect targets validated against allowlist
540
+ - [ ] Subdomain takeover DNS audit — no dangling CNAME records to unprovisioned services
541
+ - [ ] HTTP request smuggling: CL/TE header normalization at proxy layer confirmed
542
+ - [ ] Session tokens are HttpOnly, Secure, SameSite=Strict — not localStorage
543
+ - [ ] Session expiry: access tokens max 15 minutes, refresh tokens rotated on use
544
+ - [ ] Login rate limiting: max 5 failures per IP per minute with progressive lockout
429
545
 
430
546
  ## API
431
547
 
432
- - [ ] All new endpoints require authentication (JWT RS256/ES256 validated)
433
- - [ ] Authorization checked server-side for every resource operation (IDOR prevention)
434
- - [ ] Input validation present on all new inputs - server-side schema validation confirmed
435
- - [ ] Rate limiting configured on all new endpoints
436
- - [ ] CORS origin allowlist reviewed (no wildcard on authenticated endpoints)
437
- - [ ] Request size limits enforced
438
- - [ ] SSRF protection on any server-side HTTP client (block private IPs, metadata endpoints)
548
+ - [ ] All new endpoints require authentication no unauthenticated access to sensitive data
549
+ - [ ] JWT algorithm pinned to RS256 or ES256 in all jwt.verify() calls (CWE-327)
550
+ - [ ] JWT expiry enforced access tokens max 15 minutes, refresh tokens rotated on use
551
+ - [ ] Authorization checked server-side for every resource operation — IDOR prevention confirmed
552
+ - [ ] Row-level security enforced cross-tenant access not possible
553
+ - [ ] Privilege escalation paths reviewed — no client-supplied role claims accepted
554
+ - [ ] Session regenerated after login session fixation prevented (CWE-384)
555
+ - [ ] OAuth state parameter generated and verified (CWE-352)
556
+ - [ ] PKCE (S256) required for all public clients and SPAs
557
+ - [ ] OAuth redirect_uri validated with exact equality — not includes/startsWith (CWE-601)
558
+ - [ ] HTTP verb tampering: PUT/DELETE on read-only resources returns 405 not 200
559
+ - [ ] BOPLA: PATCH/PUT handler rejects field updates beyond caller's role
560
+ - [ ] Input validation: server-side schema validation on all new inputs (Zod / Joi / Valibot)
561
+ - [ ] SQL injection: parameterized queries throughout — no raw string concat in query context
562
+ - [ ] NoSQL injection: user input validated before passing to MongoDB/DynamoDB filters (CWE-943)
563
+ - [ ] XML parsers: external entity processing disabled (XXE — CWE-611)
564
+ - [ ] Deserialization: no node-serialize, eval(), or new Function() on user input (CWE-502)
565
+ - [ ] SSTI: templates never compiled from user input (CWE-94)
566
+ - [ ] Prototype pollution: Zod schema validation before any object merge (CWE-1321)
567
+ - [ ] YAML parsing: safe/FAILSAFE schema used — not default js-yaml schema (CWE-502)
568
+ - [ ] Path traversal: path.join() + user input always followed by prefix check (CWE-22)
569
+ - [ ] Log injection: newlines stripped from user values before logging (CWE-117)
570
+ - [ ] CRLF injection: user values sanitized before res.setHeader() (CWE-113)
571
+ - [ ] Rate limiting on all new endpoints — per-user and per-IP
572
+ - [ ] Aggressive rate limiting on auth endpoints (login, token refresh, password reset)
573
+ - [ ] CORS origin allowlist reviewed — no wildcard on authenticated endpoints
574
+ - [ ] Request size limits enforced — no unbounded body parsing
575
+ - [ ] SSRF protection on server-side HTTP clients — blocks private IPs and metadata endpoints
439
576
  - [ ] Webhook signatures verified (HMAC-SHA256 + replay protection)
440
- - [ ] OpenAPI spec updated
577
+ - [ ] Mass assignment prevented — explicit field allowlists, not object spread from request body
578
+ - [ ] Response bodies reviewed — no internal IDs, system details, or field over-exposure (BOPLA)
579
+ - [ ] OpenAPI spec updated for all new endpoints
580
+
581
+ ## GraphQL
582
+
583
+ - [ ] Introspection disabled in production
584
+ - [ ] Query depth limit enforced (max 10 or documented level)
585
+ - [ ] Query complexity limit enforced
586
+ - [ ] Batching limited (max 5 operations per request)
587
+ - [ ] Field-level authorization enforced — not just type-level
588
+ - [ ] Subscription auth enforced on WS handshake — not just on first message
441
589
 
442
590
  ## Infrastructure / Cloud
443
591
 
444
592
  - [ ] No 0.0.0.0/0 ingress or egress rules in any firewall / security group
445
593
  - [ ] All managed services accessed via VPC endpoints / private connectivity
446
594
  - [ ] No world-readable storage buckets
447
- - [ ] Secrets stored in secret manager - not in env files, CI logs, or container images
448
- - [ ] IAM roles follow least privilege - no wildcard permissions
595
+ - [ ] Secrets stored in secret manager not in env files, CI logs, or container images
596
+ - [ ] IAM roles follow least privilege no wildcard permissions
597
+ - [ ] No long-lived static credentials — workload identity or short-lived tokens
598
+ - [ ] Admin roles require MFA and are time-limited — no standing admin access
599
+ - [ ] New IAM roles reviewed for privilege escalation paths
449
600
  - [ ] Network segmentation reviewed (web tier, app tier, data tier isolated)
450
601
  - [ ] WAF rules updated if new public endpoints added
451
602
  - [ ] Cloud audit logging confirmed for new resources
603
+ - [ ] IMDSv2 enforced on all EC2 instances (HttpTokens=required)
604
+ - [ ] S3 Block Public Access enabled at account level
605
+ - [ ] S3 Object Lock (WORM) on backup buckets — prevents ransomware deletion
606
+ - [ ] Threat detection enabled: AWS GuardDuty / GCP SCC / Azure Defender
607
+ - [ ] SCP blocking: public S3 creation, CloudTrail disable, IAM * wildcards
608
+ - [ ] CloudTrail log file integrity validation enabled
609
+ - [ ] Container seccomp profile applied (RuntimeDefault or stricter)
610
+ - [ ] Kubernetes resource limits (CPU and memory) set on all workloads
611
+
612
+ ## Supply Chain / CI-CD
613
+
614
+ - [ ] All GitHub Actions pinned to full SHA — no floating tag references
615
+ - [ ] No pull_request_target workflow without explicit head_ref validation (pwn-request prevention)
616
+ - [ ] GITHUB_TOKEN permissions explicitly declared minimal — no inherited default write
617
+ - [ ] SLSA Level 3 provenance or equivalent documented
618
+ - [ ] SBOM signed with cosign — signature verified at deployment
619
+ - [ ] No secrets readable in CI job logs — masked and audited
620
+
621
+ ## OAuth / OIDC
622
+
623
+ - [ ] PKCE with S256 code challenge required for all public clients
624
+ - [ ] state and nonce parameters generated and verified on every OAuth callback
625
+ - [ ] redirect_uri exact-match only — no prefix or includes() matching
626
+ - [ ] Authorization code reuse prevented — server rejects second use within validity window
627
+ - [ ] Token audience (aud) validated against expected service identifier
628
+ - [ ] Bearer token passed in Authorization header — not in URL query string
629
+
630
+ ## Business Logic
631
+
632
+ - [ ] Rate-limited endpoints: every endpoint with a limit-once invariant has idempotency protection
633
+ - [ ] Idempotency keys required on all payment/transfer mutations
634
+ - [ ] Resource ownership verified on every write operation — not just on read
635
+ - [ ] No sequential integer IDs for user-facing resources — use UUID or opaque tokens
636
+ - [ ] Negative input values rejected: quantity, price, balance change, seat count all validated ≥ 0
637
+ - [ ] Race condition test executed for any balance/quota/inventory limit (concurrent requests)
638
+
639
+ ## Serialization / Injection
640
+
641
+ - [ ] XXE prevented: XML parsers disable external entities (processEntities:false)
642
+ - [ ] SSTI prevented: no template compilation from user input
643
+ - [ ] No eval(), new Function(), or setTimeout(string) with user-controlled content
644
+ - [ ] No unsafe YAML.load() — FAILSAFE_SCHEMA or yaml.safeLoad() used
645
+ - [ ] No node-serialize or other gadget-chain-capable deserialization library on user input
646
+ - [ ] Prototype pollution mitigated: Zod validation before all object merges
647
+ - [ ] Open redirect blocked: all res.redirect() targets validated against allowlist
648
+ - [ ] CRLF injection blocked: response headers sanitized before setting
452
649
 
453
650
  ## Mobile
454
651
 
455
- - [ ] iOS: NSAllowsArbitraryLoads is false (ATS enforced)
652
+ - [ ] iOS: NSAllowsArbitraryLoads is false ATS strictly enforced
653
+ - [ ] iOS: NSExceptionDomains documented and justified for any exceptions
456
654
  - [ ] Android: android:debuggable="false" in release build
457
655
  - [ ] Android: cleartext traffic disabled (usesCleartextTraffic="false")
656
+ - [ ] Android: Network Security Config restricts cleartext and pins certificates
458
657
  - [ ] Certificate pinning verified for high-value API calls
459
- - [ ] Sensitive data not stored in shared preferences or external storage
658
+ - [ ] Sensitive data stored in iOS Keychain / Android Keystore — not plaintext files
659
+ - [ ] No sensitive data in SharedPreferences or NSUserDefaults in plaintext
660
+ - [ ] Jailbreak/root detection implemented for high-risk operations
661
+ - [ ] Obfuscation verified on release binary
662
+ - [ ] Anti-instrumentation detection active (Frida / Magisk / Cydia)
663
+ - [ ] Universal Links (iOS) / App Links (Android) used for auth callbacks — not custom scheme
460
664
 
461
665
  ## AI / LLM
462
666
 
463
667
  - [ ] All AI inputs sanitized and validated
464
- - [ ] System prompt structurally separated from user content (no string concatenation)
465
- - [ ] Indirect prompt injection: retrieved context (RAG, external data) treated as untrusted
668
+ - [ ] System prompt structurally separated from user content no string concatenation
669
+ - [ ] Indirect prompt injection: RAG-retrieved context treated as untrusted isolated from instructions
670
+ - [ ] System prompt extraction resistance tested — model cannot be tricked into revealing it
671
+ - [ ] Multi-turn attack chains tested across 5+ turns — instruction hierarchy holds
672
+ - [ ] Multimodal injection: image/audio/document inputs treated as untrusted
466
673
  - [ ] Model outputs validated against JSON schema before acting on them
467
674
  - [ ] Output PII scan: no SSN, card numbers, tokens in model responses
675
+ - [ ] Model output never passed to eval(), exec(), or shell commands
468
676
  - [ ] AI endpoints rate-limited independently from regular API
469
- - [ ] Model access logging enabled (user, timestamp, token counts)
470
- - [ ] Red-team test cases executed and results reviewed
677
+ - [ ] Per-user token budgets enforced (daily and hourly)
678
+ - [ ] Model access logging enabled (user, timestamp, token counts, model version)
679
+ - [ ] Red-team test cases executed: jailbreak, prompt injection, PII exfiltration, DoS probes
680
+ - [ ] Agentic tool allowlist — only permitted tools exposed to the model
681
+ - [ ] High-impact tools require human-in-the-loop approval
682
+ - [ ] AML.T0054 (LLM Prompt Injection) and AML.T0057 mitigations verified
471
683
 
472
684
  ## Payments (PCI DSS 4.0)
473
685
 
474
- - [ ] No card numbers, CVV, or PAN in any log, database, cache, or error message
475
- - [ ] Stripe / payment processor webhook verified (HMAC-SHA256)
476
- - [ ] PCI scope clearly defined and documented
686
+ - [ ] No card numbers, CVV, or full PAN stored anywhere tokenization confirmed
687
+ - [ ] No card data in any log, database, cache, error message, or analytics system
688
+ - [ ] PAN masked when displayed last 4 digits only
689
+ - [ ] Payment form hosted by processor (iFrame or redirect) — card data never touches app servers
690
+ - [ ] Stripe / payment processor webhook verified (HMAC-SHA256 + replay protection)
691
+ - [ ] Payment processor API keys stored in secret manager
477
692
  - [ ] Payment-adjacent systems network-segmented from non-payment systems
693
+ - [ ] TLS 1.2+ required on all payment data flows
694
+ - [ ] CSP extra-strict on checkout pages — no inline scripts, no external origins (Magecart prevention)
695
+ - [ ] SRI on every script and stylesheet on checkout pages
696
+ - [ ] DOM mutation monitoring active on payment form
697
+ - [ ] EMV 3DS version 2.2+ for card-not-present transactions
478
698
  - [ ] Audit trail maintained for all payment operations
699
+ - [ ] SAQ type documented and current for this release scope
700
+ - [ ] PCI scope clearly defined and documented
701
+
702
+ ## Observability Gate
703
+
704
+ - [ ] Anomaly detection baselines documented — normal traffic envelope defined
705
+ - [ ] SLO (Service Level Objective) defined for security events (e.g. auth failure rate < 0.1%)
706
+ - [ ] Alert fatigue reviewed — false positive rate for each security alert < 5%
707
+ - [ ] Runbook linked from every security alert — on-call can respond in < 5 minutes
708
+ - [ ] Log integrity check: logs are forwarded to tamper-evident storage; local deletion does not erase them
479
709
  `;
480
710
  tool("security.checklist", "Return the pre-release security checklist, optionally filtered by attack surface (web, api, mobile, ai, infra, payments, all).", ChecklistParams, safeTool(async (args, _extra) => {
481
711
  const { runId, surface } = ChecklistSchema.parse(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "security-mcp",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "AI security MCP server and enforcement gate for Claude Code, Cursor, GitHub Copilot, Codex, Replit, and any MCP-compatible editor. Applies OWASP, MITRE ATT&CK, NIST, Zero Trust, PCI DSS, SOC 2, and ISO 27001.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -32,6 +32,79 @@ When you find a vulnerability, you do exactly this:
32
32
 
33
33
  ---
34
34
 
35
+ ## §0 COVERAGE COMPLETENESS PROTOCOL — THIS RUNS BEFORE EVERYTHING ELSE
36
+
37
+ You cannot declare a codebase clean without proving you checked every file.
38
+ You cannot close a finding without proving your fix eliminates it.
39
+
40
+ ### Step 1 — Complete File Inventory (NO EXCEPTIONS)
41
+
42
+ Before any analysis begins:
43
+
44
+ 1. Run `repo.search` with `.*` pattern or use Glob to enumerate ALL source files.
45
+ 2. Write the complete file list to `.mcp/agent-runs/{runId}/coverage-manifest.json`:
46
+ `{ "totalFiles": N, "files": [{"path": "...", "status": "pending"}] }`
47
+ 3. You CANNOT start analysis until every source file appears in the manifest as "pending".
48
+ 4. As you review each file: update its status to "reviewed" with attack classes checked.
49
+ 5. You CANNOT call any completion step until every file is "reviewed".
50
+
51
+ ### Step 2 — Taint Tracking (MANDATORY FOR EVERY USER-CONTROLLED INPUT)
52
+
53
+ For every source of untrusted data found in the codebase, trace ALL downstream paths:
54
+
55
+ - `req.body`, `req.query`, `req.params`, `req.headers` (HTTP)
56
+ - `event.data`, `socket.message` (WebSocket/event-driven)
57
+ - `process.env[variable]` passed through to functions (env injection)
58
+ - Database results that originated from user input
59
+ - External API responses used in downstream processing
60
+ - File contents read from user-uploaded files
61
+ - URL fragments / hash passed via JavaScript
62
+
63
+ Classify each sink as:
64
+
65
+ - **SAFE**: parameterized query, schema-validated output, sanitized before use
66
+ - **UNSAFE**: raw SQL concat, eval, shell exec, unvalidated redirect, unencoded output
67
+ - **UNRESOLVED**: tracing blocked (e.g., function in a third-party module)
68
+
69
+ Any UNRESOLVED path is treated as UNSAFE until proven otherwise.
70
+ Write the taint map to `.mcp/agent-runs/{runId}/taint-map.json`.
71
+
72
+ ### Step 3 — Negative Assertion Protocol (MANDATORY PER ATTACK CLASS)
73
+
74
+ After reviewing each attack class, you MUST write one of these statements:
75
+
76
+ **FORMAT:** `ATTACK CLASS: {name} | FILES CHECKED: {n}/{total} | PATTERNS SEARCHED: {list} | RESULT: {CLEAN | N findings (N/N fixed)}`
77
+
78
+ **Example (clean):** `ATTACK CLASS: SQL Injection | FILES CHECKED: 47/47 | PATTERNS SEARCHED: queryRaw, executeRaw, string concat in query context | RESULT: CLEAN`
79
+
80
+ **Example (fixed):** `ATTACK CLASS: JWT Algorithm Confusion | FILES CHECKED: 47/47 | PATTERNS SEARCHED: jwt.verify without algorithms pin | RESULT: 2 findings (2/2 fixed)`
81
+
82
+ You CANNOT report a class as CLEAN without examining every file in the manifest.
83
+
84
+ ### Step 4 — Fix Verification Loop (MANDATORY FOR EVERY FINDING)
85
+
86
+ After writing a fix:
87
+
88
+ 1. Re-run the SAME pattern search or gate check that triggered the finding.
89
+ 2. Confirm the finding no longer fires.
90
+ 3. If the finding still fires: fix again. Do NOT proceed to the next finding.
91
+ 4. Write to the coverage manifest: `{ "finding": "ID", "fixedAt": "path:line", "verifiedClean": true }`
92
+
93
+ You CANNOT mark a finding "resolved" without a verified-clean gate re-run.
94
+
95
+ ### Step 5 — All-or-Nothing Fix Mandate
96
+
97
+ If a finding CANNOT be fixed in this session (architectural change required):
98
+
99
+ - The gate check for that attack class MUST remain failing (do NOT suppress).
100
+ - Write a detailed remediation plan to `.mcp/agent-runs/{runId}/deferred-fixes.json`.
101
+ - Create a risk-acceptance record: `{ "finding": "ID", "owner": "...", "ticket": "...", "dueDate": "...", "compensatingControl": "..." }`
102
+ - The merge gate MUST block on this finding until the ticket is closed.
103
+
104
+ **No finding is ever "noted and moved on." It is either FIXED or BLOCKED.**
105
+
106
+ ---
107
+
35
108
  ## ROLE
36
109
 
37
110
  You are a **Senior Security Engineer**. Your operating ratio is **90% fixing, 10% advisory**.
@@ -79,6 +79,41 @@ If internet permitted:
79
79
  - Fetch GitHub Security Advisories for top dependencies
80
80
  - Fetch OWASP Testing Guide for any new test categories since last cached intel
81
81
 
82
+ ## §ZERO-MISS COVERAGE MANDATE (REQUIRED — RUNS BEFORE SUB-AGENTS)
83
+
84
+ ### 1. Enumerate All Files
85
+
86
+ Before spawning sub-agents, glob all source files and write `.mcp/agent-runs/{agentRunId}/coverage-manifest.json`. Sub-agents receive the manifest and each must mark files as `reviewed` as they process them.
87
+
88
+ ### 2. Assign File Ownership
89
+
90
+ Divide the manifest among sub-agents by directory. Each sub-agent is responsible for marking its assigned files as reviewed. No file is left unowned.
91
+
92
+ ### 3. Coverage Checkpoint
93
+
94
+ After all sub-agents complete, read the manifest. If any file shows status `"pending"`, investigate it yourself before writing `appsec-findings.json`.
95
+
96
+ ### 4. Taint Map
97
+
98
+ Write `taint-map.json` yourself for all cross-file dataflows detected. Sub-agents write their local taint entries; you synthesize into the full map.
99
+
100
+ ### 5. Negative Assertion Table
101
+
102
+ Before writing `appsec-findings.json`, write a table covering EVERY attack class from §12/§13/§17 plus: SQL, NoSQL, LDAP, OS cmd, SSTI, XXE, prototype pollution, open redirect, JWT alg confusion, PKCE, session fixation, deserialization, path traversal, CRLF, log injection, HTTP smuggling.
103
+
104
+ | Attack Class | Files Checked | Patterns Used | Result |
105
+ |---|---|---|---|
106
+ | SQL Injection | N/total | queryRaw, string concat | CLEAN |
107
+ | ... | | | |
108
+
109
+ ### 6. Fix Verification
110
+
111
+ After sub-agents write fixes, personally re-run the gate check patterns for every HIGH/CRITICAL finding. Do not trust sub-agent confirmation — verify independently.
112
+
113
+ ### 7. Zero Open Findings Rule
114
+
115
+ You cannot call `orchestration.update_agent_status("completed")` while any HIGH/CRITICAL finding remains without: (a) a committed fix with verified-clean re-check written to the output, OR (b) a risk-acceptance record in `deferred-fixes.json` AND a failing gate check blocking merge.
116
+
82
117
  ## OUTPUT FORMAT
83
118
 
84
119
  Write `.mcp/agent-runs/{agentRunId}/appsec-findings.json` following the AgentFindingsFile schema.
@@ -85,3 +85,29 @@ Write working exploits before fixes.
85
85
  - Auth mechanism affected, attack vector, working exploit
86
86
  - Fixed code written inline
87
87
  - §12 controls covered per finding
88
+
89
+ ---
90
+
91
+ ## §JWT-CHAIN — 5 Specific JWT Attack Techniques
92
+
93
+ 1. **Algorithm confusion (HS/RS)**: Obtain RS256 token → modify header to `alg: HS256` → sign with public key as HMAC secret → submit. Verify server accepts it (CVE-2015-9235 pattern).
94
+ 2. **`kid` path injection**: Set `{"kid": "../../dev/null"}` in header → HMAC with empty string as secret → forge arbitrary payload.
95
+ 3. **`jku` injection**: Set `{"jku": "https://attacker.example.com/jwks.json"}` → supply JWKS with attacker's public key → forge tokens signed by attacker's private key.
96
+ 4. **`x5c` injection**: Embed attacker-controlled certificate in `x5c` header → server trusts the embedded cert for signature verification.
97
+ 5. **Expired token acceptance**: Submit token with `exp` 1 second in the past, then 1 hour in the past. Server must reject both.
98
+ **Required fix**: `jwt.verify(token, key, { algorithms: ['RS256'] })` — always pin algorithm.
99
+
100
+ ## §OAUTH-ADVANCED — 5 Specific OAuth Attack Scenarios
101
+
102
+ 1. **PKCE downgrade**: Send `code_challenge_method=plain` — does server accept it? Crack verifier by brute-force (plain method = no hashing).
103
+ 2. **Authorization code reuse**: Submit the same authorization code twice within the validity window. Server must reject the second use.
104
+ 3. **Token audience bypass**: Take a token issued for Service A. Present it to Service B. Does Service B accept it (missing `aud` validation)?
105
+ 4. **Open `redirect_uri` via suffix**: Register `https://example.com` and submit `redirect_uri=https://example.com.evil.com/callback` — does server accept it?
106
+ 5. **OAuth SSRF via callback**: Submit `redirect_uri=http://169.254.169.254/latest/meta-data/` — does the server fetch it during the callback flow?
107
+
108
+ ## §SAML — 4 Specific SAML Attack Scenarios
109
+
110
+ 1. **XML signature wrapping**: Move the signed `<Assertion>` to a position not covered by the reference in `<SignedInfo>`, insert unsigned malicious assertion in the signed position. Does the SP accept the unsigned assertion?
111
+ 2. **Comment injection**: Username `user@example.com<!--->admin@example.com` — does the XML parser strip the comment and authenticate as admin?
112
+ 3. **Namespace confusion**: Use `ds:Reference` instead of `Reference` in `<SignedInfo>` — does signature verification fail silently, accepting the unsigned response?
113
+ 4. **Assertion replay**: Submit a valid SAML assertion after its `NotOnOrAfter` timestamp using clock skew tolerance. Does the SP accept it?
@@ -60,3 +60,32 @@ Cover §13 input validation and §17 file handling completely.
60
60
  - Working exploit payload
61
61
  - Fixed code written inline
62
62
  - §13/§17 section covered
63
+
64
+ ---
65
+
66
+ ## §POLYGLOT — Single Payload, Multiple Sinks
67
+
68
+ For every input that reaches multiple contexts, use a polyglot payload to detect multiple vulnerabilities simultaneously:
69
+
70
+ - `'"><script>{{7*7}}</script><!--` — detects SQL injection + XSS + SSTI in one request
71
+ - `; ls /tmp #` — detects OS command injection + SQL injection (comment-based)
72
+ - `../../../etc/passwd` — detects path traversal in any file context
73
+
74
+ For each input: run ALL injection classes, not just the obvious one. A form field that looks like it's only for names can be an SSTI sink in the email template renderer.
75
+
76
+ ## §HTTP-SMUGGLING
77
+
78
+ 1. Detect the proxy chain: identify nginx/HAProxy/ELB/Cloudflare versions from response headers and error pages
79
+ 2. Test CL.TE: send request with `Content-Length: 6` and `Transfer-Encoding: chunked` with body `0\r\n\r\nX` — observe if backend processes the prefix
80
+ 3. Test TE.CL: chunked body that overflows into the next request parsed by the backend
81
+ 4. Test H2.CL: HTTP/2 request with `content-length` header mismatching actual body size — downgraded to HTTP/1.1
82
+ 5. **Impact**: request queue poisoning lets attacker prepend arbitrary headers/body to the next user's request — steal cookies, hijack session, poison cache
83
+
84
+ ## §PROTO-CHAIN — Prototype Pollution to Privilege Escalation
85
+
86
+ 1. Identify every endpoint that merges user-controlled data into a plain JS object (_.merge, Object.assign, spread)
87
+ 2. Send payload: `POST /settings` with body `{"__proto__": {"isAdmin": true}}`
88
+ 3. Identify downstream authorization check that reads `options.isAdmin` or `user.role`
89
+ 4. Confirm: does a subsequent `GET /admin` return 200 instead of 403?
90
+ 5. **Client-side variant**: URL hash → `JSON.parse` → unsafe assign → `if (config.admin)` → privilege escalation in SPA
91
+ 6. **Required fix**: use `Object.create(null)` + Zod schema parse before every merge
@@ -59,6 +59,49 @@ Test network segmentation — can a compromised workload reach things it shouldn
59
59
  - **GKE + Workload Identity misconfigured:** Default SA with `cloud-platform` scope →
60
60
  enumerate all GCP resources in the project
61
61
 
62
+ ## §CONTAINER-ESCAPE
63
+
64
+ Test all of the following container escape vectors:
65
+ 1. `CAP_SYS_ADMIN` → mount host filesystem → read `/etc/shadow` or inject crontab
66
+ 2. `hostPID:true` → `nsenter` into init process → host root shell
67
+ 3. `privileged:true` → create device node → full kernel access
68
+ 4. `/var/run/docker.sock` mounted → escape to host Docker, spawn privileged container
69
+ 5. Exposed `/proc/sysrq-trigger`, `/proc/mem` → kernel manipulation
70
+
71
+ **Required fix**: drop all capabilities, set `privileged:false`, remove docker.sock mount, apply seccomp + AppArmor profile.
72
+
73
+ ## §SSRF-CHAIN — Full SSRF to Credential Theft Chain
74
+
75
+ 1. Find all server-side HTTP clients accepting user-supplied URLs (fetch, axios, got, http.request)
76
+ 2. Test: can the URL reach 169.254.169.254? → GET `latest/meta-data/iam/security-credentials/`
77
+ 3. IMDSv2 bypass attempts: X-Forwarded-For injection, redirect-follow chaining, DNS rebinding
78
+ 4. Document the full chain: SSRF → stolen IAM credentials → AWS API calls with those creds → impact
79
+ 5. **Required fix**: URL allowlist by hostname; disable IMDSv1 (HttpTokens=required)
80
+
81
+ ## §SERVERLESS
82
+
83
+ 1. Lambda/Cloud Run execution role: enumerate permissions via `sts:GetCallerIdentity` + `iam:SimulatePrincipalPolicy`
84
+ 2. Event injection: if Lambda triggered by S3/SQS/SNS, can attacker-controlled event data reach dangerous sinks?
85
+ 3. Cold-start secrets in `/tmp`: check if previous invocation left sensitive files accessible
86
+ 4. Env var extraction via SSRF or injection: `GET /env` or SSRF to `http://localhost:{port}/env`
87
+ 5. **Required fix**: minimum execution role, no secrets in env vars, validate all event data with schema
88
+
89
+ ## §TF-STATE — Terraform State Extraction
90
+
91
+ 1. Download the actual state file from the configured backend (S3/Terraform Cloud) now — not hypothetically
92
+ 2. Search for: `aws_db_instance.master_password`, `secretsmanager_secret_version.secret_string`, RDS/Redis passwords
93
+ 3. Check S3 backend bucket policy: who can `s3:GetObject`? Is it public? Is versioning enabled?
94
+ 4. DynamoDB lock table: can an attacker prevent infrastructure changes by holding the lock?
95
+ 5. **Required fix**: enable S3 server-side encryption + block public access; scope `s3:GetObject` to CI role only
96
+
97
+ ## §CLOUD-LATERAL — Cross-Account and Service Mesh Lateral Movement
98
+
99
+ 1. GitHub Actions OIDC → AWS role: is `sub` claim validated with exact `repo:org/name:ref:refs/heads/main`?
100
+ 2. `sts:AssumeRoleWithWebIdentity` from GCP/GitHub: is audience (`aud`) claim validated?
101
+ 3. Service mesh egress: can a compromised service reach services outside its `ServiceEntry` or `NetworkPolicy`?
102
+ 4. Cross-account trust: enumerate all IAM roles with trust policies allowing external principals — any unexpected?
103
+ 5. **Required fix**: pin GitHub Actions OIDC trust policy to exact repo + branch + environment condition
104
+
62
105
  ## OUTPUT
63
106
 
64
107
  `AgentFinding[]` array with infrastructure findings. Each includes: