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.
- package/README.md +145 -18
- package/defaults/control-catalog.json +200 -0
- package/dist/cli/index.js +82 -5
- package/dist/cli/install.js +36 -6
- package/dist/cli/onboarding.js +6 -0
- package/dist/gate/checks/auth-deep.js +231 -0
- package/dist/gate/checks/injection-deep.js +205 -0
- package/dist/gate/policy.js +5 -1
- package/dist/mcp/server.js +271 -41
- package/package.json +1 -1
- package/prompts/SECURITY_PROMPT.md +73 -0
- package/skills/appsec-code-auditor/SKILL.md +35 -0
- package/skills/auth-session-hacker/SKILL.md +26 -0
- package/skills/injection-specialist/SKILL.md +29 -0
- package/skills/pentest-infra/SKILL.md +43 -0
- package/skills/pentest-team/SKILL.md +47 -0
- package/skills/pentest-web-api/SKILL.md +53 -0
- package/skills/senior-security-engineer/SKILL.md +203 -2
package/README.md
CHANGED
|
@@ -17,15 +17,18 @@ Works with **Claude Code, GitHub Copilot, Cursor, Codex, Replit**, and any MCP-c
|
|
|
17
17
|
|
|
18
18
|
## Table of Contents
|
|
19
19
|
|
|
20
|
+
- [What's New in 1.1.4](#whats-new-in-114)
|
|
20
21
|
- [What Problem Does This Solve?](#what-problem-does-this-solve)
|
|
21
22
|
- [Who Is This For?](#who-is-this-for)
|
|
22
|
-
- [Two Modes - Pick Your Depth](#two-modes
|
|
23
|
-
- [Quick Start - Install in 60 Seconds](#quick-start
|
|
23
|
+
- [Two Modes - Pick Your Depth](#two-modes---pick-your-depth)
|
|
24
|
+
- [Quick Start - Install in 60 Seconds](#quick-start---install-in-60-seconds)
|
|
24
25
|
- [Step-by-Step Installation Guide](#step-by-step-installation-guide)
|
|
25
26
|
- [Claude Code](#step-by-step-claude-code)
|
|
26
27
|
- [Cursor](#step-by-step-cursor)
|
|
27
28
|
- [VS Code / GitHub Copilot](#step-by-step-vs-code--github-copilot)
|
|
29
|
+
- [Windsurf](#step-by-step-windsurf)
|
|
28
30
|
- [Manual Configuration](#manual-configuration-any-mcp-editor)
|
|
31
|
+
- [Verify Your Installation](#verify-your-installation)
|
|
29
32
|
- [How to Run Your First Security Review](#how-to-run-your-first-security-review)
|
|
30
33
|
- [CI/CD Security Gate](#cicd-security-gate)
|
|
31
34
|
- [What Gets Fixed Automatically](#what-gets-fixed-automatically)
|
|
@@ -40,6 +43,57 @@ Works with **Claude Code, GitHub Copilot, Cursor, Codex, Replit**, and any MCP-c
|
|
|
40
43
|
|
|
41
44
|
---
|
|
42
45
|
|
|
46
|
+
## What's New in 1.1.4
|
|
47
|
+
|
|
48
|
+
### 20 Checks (up from 18) - Deep Injection + Deep Auth Modules
|
|
49
|
+
|
|
50
|
+
Two new deep-check modules run automatically for web and API surfaces:
|
|
51
|
+
|
|
52
|
+
**`checkInjectionDeep`** — 11 new patterns: XXE (CWE-611), SSTI (CWE-94), prototype pollution (CWE-1321), open redirect (CWE-601), NoSQL operator injection (CWE-943), CRLF injection (CWE-113), unsafe YAML load (CWE-502), unsafe deserialization, path traversal (CWE-22), log injection (CWE-117), SSRF (CWE-918).
|
|
53
|
+
|
|
54
|
+
**`checkAuthDeep`** — 12 new patterns: JWT algorithm confusion / `alg:none` (CWE-327), session fixation (CWE-384), OAuth missing state parameter (CWE-352), OAuth `redirect_uri` open redirect (CWE-601), PKCE not enforced (RFC 7636), hardcoded JWT secret (CWE-798), missing rate limit on auth endpoints (CWE-307), plaintext password comparison (CWE-256), SAML signature validation disabled (CWE-347), insecure cookie flags (CWE-1004/614), refresh token not rotated (CWE-613), JWT HS/RS confusion (CVE-2015-9235 pattern).
|
|
55
|
+
|
|
56
|
+
### Coverage Completeness Protocol (§0)
|
|
57
|
+
|
|
58
|
+
Every security review now runs a mandatory 5-step protocol before reporting any result:
|
|
59
|
+
|
|
60
|
+
1. **Complete file inventory** — enumerate all source files into `coverage-manifest.json`; no attack class can be called CLEAN without checking every file.
|
|
61
|
+
2. **Taint tracking** — trace every user-controlled input (`req.body`, `req.query`, WebSocket, env, file uploads, external API responses) to all downstream sinks, classifying each SAFE / UNSAFE / UNRESOLVED.
|
|
62
|
+
3. **Negative assertions** — after each attack class: `ATTACK CLASS: {name} | FILES: N/N | PATTERNS: {list} | RESULT: CLEAN`.
|
|
63
|
+
4. **Fix verification loop** — after every fix, re-run the triggering check and confirm it no longer fires before advancing.
|
|
64
|
+
5. **All-or-nothing mandate** — every HIGH/CRITICAL finding is either FIXED (verified clean) or BLOCKED (risk-accepted, gate failing, remediation plan written to `deferred-fixes.json`).
|
|
65
|
+
|
|
66
|
+
### Enhanced Threat Model Template
|
|
67
|
+
|
|
68
|
+
The `security.threat_model` tool now generates a more complete template including LINDDUN privacy threat analysis (Linking, Identifying, Non-repudiation, Detecting, Data Disclosure, Unawareness, Non-compliance), TRIKE risk matrix (actor-action-asset-risk), DREAD scoring, attack trees for the top 3 critical paths, adversary profiles mapped to ATT&CK techniques, and supply chain threat enumeration.
|
|
69
|
+
|
|
70
|
+
### Expanded Release Checklists
|
|
71
|
+
|
|
72
|
+
All domain-specific release checklists now include:
|
|
73
|
+
|
|
74
|
+
- **OAuth/OIDC** — PKCE with S256, state/nonce verification, exact-match `redirect_uri`, code reuse prevention, audience validation
|
|
75
|
+
- **Business Logic** — idempotency keys on payment mutations, negative input validation, race condition testing for balance/quota/inventory
|
|
76
|
+
- **Serialization/Injection** — XXE, SSTI, unsafe YAML, deserialization, prototype pollution, open redirect, CRLF in every checklist
|
|
77
|
+
- **AI/LLM** — system prompt extraction resistance, multi-turn attack chains, multimodal injection, agentic tool allowlist, AML.T0054/T0057 mitigations
|
|
78
|
+
- **Payments (PCI DSS 4.0)** — PAN masking, DOM mutation monitoring, EMV 3DS 2.2+, Magecart prevention (SRI on checkout pages)
|
|
79
|
+
- **Observability Gate** (new) — anomaly detection baselines, SLO definitions for security events, alert fatigue review, runbook coverage
|
|
80
|
+
|
|
81
|
+
### Windsurf Support
|
|
82
|
+
|
|
83
|
+
The installer now detects and configures Windsurf (`~/.windsurf/mcp.json`) automatically alongside Claude Code, Cursor, and VS Code.
|
|
84
|
+
|
|
85
|
+
### `doctor` Command
|
|
86
|
+
|
|
87
|
+
Verify your installation health at any time:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx -y security-mcp@latest doctor
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Checks Node.js version, editor configs, and skill files — prints PASS/FAIL per check with actionable fix commands.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
43
97
|
## What Problem Does This Solve?
|
|
44
98
|
|
|
45
99
|
When you use an AI coding assistant to build features fast, security is easy to skip - not because you don't care, but because:
|
|
@@ -77,19 +131,19 @@ A single elite security engineer agent that reviews your code, finds vulnerabili
|
|
|
77
131
|
|
|
78
132
|
### `/ciso-orchestrator` - A Full Security Program in One Command
|
|
79
133
|
|
|
80
|
-
|
|
134
|
+
39 specialist agents across 3 phases. Phase 1: 7 lead agents run in parallel, each commanding its own team of sub-agents — threat modeling, deep code analysis, cloud infrastructure, supply chain, AI/LLM red team, mobile, and cryptography. Phase 2: adversarial penetration testing and compliance synthesis run in parallel after Phase 1 completes. Phase 3: findings are merged, deduplicated, and attested. Every domain has a dedicated specialist — an injection attacker, a JWT/OAuth hacker, a cloud privilege escalation analyst, a prompt injection specialist, a TLS auditor, a pentest team that reads the threat model as its attack brief, and a compliance analyst mapping every finding to PCI DSS 4.0, SOC 2, ISO 27001, NIST 800-53, HIPAA, and GDPR. Agents learn from each run and improve over time. 86 specialist skills registered in the registry — loaded on demand based on detected stack. Optionally fetches live CVE, CISA KEV, and ATT&CK data. Produces a merged findings report with full compliance mapping and a signed attestation.
|
|
81
135
|
|
|
82
|
-
**Use this before major releases, compliance audits, or security reviews. -> [See the full
|
|
136
|
+
**Use this before major releases, compliance audits, or security reviews. -> [See the full 39-agent architecture](#ciso-orchestrator-flow-39-agents)**
|
|
83
137
|
|
|
84
138
|
---
|
|
85
139
|
|
|
86
140
|
| | `/senior-security-engineer` | `/ciso-orchestrator` |
|
|
87
141
|
| --- | --- | --- |
|
|
88
|
-
| **What it is** | Single expert agent |
|
|
142
|
+
| **What it is** | Single expert agent | 39-agent multi-phase security program |
|
|
89
143
|
| **Best for** | Daily development, PR reviews, targeted hardening | Pre-launch audits, compliance prep, incident response |
|
|
90
144
|
| **Speed** | Seconds to minutes | Minutes to hours |
|
|
91
145
|
| **Scope** | You choose: recent changes, full codebase, or specific files | Always full - every surface, every framework |
|
|
92
|
-
| **Agents** | 1 |
|
|
146
|
+
| **Agents** | 1 | 39 (9 leads + 30 sub-agents) |
|
|
93
147
|
| **Output** | Inline code fixes + SHA-256 attestation | Full domain reports + merged findings + attestation |
|
|
94
148
|
| **API cost** | Low | High |
|
|
95
149
|
| **Internet** | Not required | Optional (enriches findings with live CVEs, CISA KEV, MITRE ATT&CK) |
|
|
@@ -112,7 +166,7 @@ Restart your editor. Then in Claude Code:
|
|
|
112
166
|
|
|
113
167
|
That's it. The engineer will ask how you want to scope the review, then find and fix security issues in your code.
|
|
114
168
|
|
|
115
|
-
For a full
|
|
169
|
+
For a full 39-agent deep audit:
|
|
116
170
|
|
|
117
171
|
```text
|
|
118
172
|
/ciso-orchestrator
|
|
@@ -257,6 +311,45 @@ You should see:
|
|
|
257
311
|
|
|
258
312
|
---
|
|
259
313
|
|
|
314
|
+
### Step-by-Step: Windsurf
|
|
315
|
+
|
|
316
|
+
**Step 1 - Run the installer:**
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
npx -y security-mcp@latest install
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
This auto-detects Windsurf and writes to `~/.windsurf/mcp.json`.
|
|
323
|
+
|
|
324
|
+
**Step 2 - Verify:**
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
cat ~/.windsurf/mcp.json
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Expected output:
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"mcpServers": {
|
|
335
|
+
"security-mcp": {
|
|
336
|
+
"command": "npx",
|
|
337
|
+
"args": ["-y", "security-mcp@latest", "serve"]
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Step 3 - Restart Windsurf.**
|
|
344
|
+
|
|
345
|
+
**Step 4 - In the Windsurf AI chat, type:**
|
|
346
|
+
|
|
347
|
+
```text
|
|
348
|
+
Use /senior-security-engineer to review my recent changes
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
260
353
|
### Manual Configuration (Any MCP Editor)
|
|
261
354
|
|
|
262
355
|
If the installer doesn't detect your editor, or you prefer to configure manually:
|
|
@@ -343,6 +436,28 @@ npx -y security-mcp@latest install --dry-run
|
|
|
343
436
|
|
|
344
437
|
---
|
|
345
438
|
|
|
439
|
+
## Verify Your Installation
|
|
440
|
+
|
|
441
|
+
After installing, confirm everything is wired up correctly:
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
npx -y security-mcp@latest doctor
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
This checks your Node.js version, editor config files, and installed skills — and prints `[PASS]` or `[FAIL]` per check with a fix command if anything is missing.
|
|
448
|
+
|
|
449
|
+
Example output:
|
|
450
|
+
|
|
451
|
+
```text
|
|
452
|
+
[PASS] Node.js 22.x
|
|
453
|
+
[PASS] Claude Code config (~/.claude/settings.json)
|
|
454
|
+
[PASS] senior-security-engineer skill (~/.claude/skills/senior-security-engineer/SKILL.md)
|
|
455
|
+
|
|
456
|
+
All checks passed. Restart your editor, then type /senior-security-engineer.
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
346
461
|
## How to Run Your First Security Review
|
|
347
462
|
|
|
348
463
|
### Daily Workflow: `/senior-security-engineer`
|
|
@@ -365,7 +480,7 @@ npx -y security-mcp@latest install --dry-run
|
|
|
365
480
|
|
|
366
481
|
1. Call `security.start_review` to create a tracked run
|
|
367
482
|
2. Build a scan plan covering all relevant OWASP/NIST/ATT&CK controls
|
|
368
|
-
3. Run
|
|
483
|
+
3. Run 20 security checks in parallel across secrets, dependencies, crypto, auth, injection, cloud config, AI/LLM, mobile, and more
|
|
369
484
|
4. Write fixes directly into your code for every finding it can remediate
|
|
370
485
|
5. Generate a SHA-256 attested report at `.mcp/reports/{runId}.attestation.json`
|
|
371
486
|
|
|
@@ -398,7 +513,7 @@ The orchestrator will ask:
|
|
|
398
513
|
- **Yes** - agents enrich findings with live threat intelligence. More accurate, more current.
|
|
399
514
|
- **No** - agents use cached intel. Still comprehensive, no external calls made.
|
|
400
515
|
|
|
401
|
-
**Step 3 - Wait for Phase 1 (7 lead agents
|
|
516
|
+
**Step 3 - Wait for Phase 1 (7 lead agents running in parallel, each commanding their domain-specific sub-agents — 25 sub-agents total across Phase 1).**
|
|
402
517
|
|
|
403
518
|
Each agent writes findings to `.mcp/agent-runs/{agentRunId}/`.
|
|
404
519
|
|
|
@@ -463,7 +578,7 @@ jobs:
|
|
|
463
578
|
|
|
464
579
|
### What the CI Gate Checks
|
|
465
580
|
|
|
466
|
-
The gate runs **
|
|
581
|
+
The gate runs **20 checks in parallel** against your diff:
|
|
467
582
|
|
|
468
583
|
| Category | What It Catches |
|
|
469
584
|
| --- | --- |
|
|
@@ -486,6 +601,8 @@ The gate runs **18 checks in parallel** against your diff:
|
|
|
486
601
|
| **AI red-team** | Static + optional dynamic probes against AI endpoints |
|
|
487
602
|
| **Exceptions** | Validates any active security exceptions are non-expired and properly approved |
|
|
488
603
|
| **Baseline regression** | Detects when previously-satisfied controls go missing (BASELINE_REGRESSION HIGH finding injected on regression) |
|
|
604
|
+
| **Deep injection** | XXE, SSTI, prototype pollution, open redirect, NoSQL operator injection, CRLF, unsafe YAML load, deserialization, path traversal, log injection, SSRF (11 new patterns) |
|
|
605
|
+
| **Deep auth** | JWT algorithm confusion, session fixation, OAuth missing state, OAuth open redirect_uri, PKCE not enforced, hardcoded JWT secret, missing rate limit on auth endpoints, plaintext password compare, SAML signature disabled, insecure cookie flags, refresh token not rotated, JWT HS/RS confusion (12 new patterns) |
|
|
489
606
|
|
|
490
607
|
### Customize the Gate Policy
|
|
491
608
|
|
|
@@ -621,7 +738,7 @@ app.use(helmet({
|
|
|
621
738
|
│ Your Editor (Claude Code) │
|
|
622
739
|
│ │
|
|
623
740
|
│ /senior-security-engineer /ciso-orchestrator │
|
|
624
|
-
│ (single expert agent) (
|
|
741
|
+
│ (single expert agent) (39-agent security program) │
|
|
625
742
|
│ │ │ │
|
|
626
743
|
└──────────┼────────────────────────────────┼───────────────────┘
|
|
627
744
|
│ │
|
|
@@ -652,15 +769,16 @@ app.use(helmet({
|
|
|
652
769
|
┌──────────────────────────────────────────────────────────────┐
|
|
653
770
|
│ Policy Gate Engine (src/gate/policy.ts) │
|
|
654
771
|
│ │
|
|
655
|
-
│
|
|
772
|
+
│ 20 checks run in parallel: │
|
|
656
773
|
│ checkSecrets checkDependencies checkApi checkInfra │
|
|
657
774
|
│ checkCrypto checkMobileIos checkMobileAndroid │
|
|
658
775
|
│ checkAi checkGraphQL checkKubernetes │
|
|
659
776
|
│ checkDatabase checkDlp checkWebNextjs │
|
|
660
|
-
│ runSbomChecks runAiRedteamChecks runRuntimeChecks
|
|
777
|
+
│ runSbomChecks runAiRedteamChecks runRuntimeChecks │
|
|
778
|
+
│ checkInjectionDeep (11 patterns) checkAuthDeep (12 patterns)│
|
|
661
779
|
│ │
|
|
662
780
|
│ Surface detection -> Control catalog -> Exception handling -> │
|
|
663
|
-
│ Confidence scoring -> PASS / FAIL
|
|
781
|
+
│ Coverage manifest -> Taint map -> Confidence scoring -> PASS / FAIL │
|
|
664
782
|
└──────────────────────────────────────────────────────────────┘
|
|
665
783
|
```
|
|
666
784
|
|
|
@@ -684,10 +802,17 @@ User: /senior-security-engineer
|
|
|
684
802
|
└── STRIDE + PASTA + ATT&CK template for changed surface
|
|
685
803
|
│
|
|
686
804
|
▼
|
|
805
|
+
§0 Coverage Completeness Protocol (runs first)
|
|
806
|
+
├── enumerate ALL source files → coverage-manifest.json
|
|
807
|
+
├── taint-trace every user-controlled input → taint-map.json
|
|
808
|
+
├── negative assertion per attack class: "FILES: N/N | RESULT: CLEAN"
|
|
809
|
+
└── fix verification loop: re-run check after every fix, confirm CLEAN
|
|
810
|
+
│
|
|
811
|
+
▼
|
|
687
812
|
security.run_pr_gate(runId, mode, targets)
|
|
688
813
|
├── git diff / glob targets -> changed files list
|
|
689
814
|
├── detectSurfaces() -> web? api? infra? mobile? ai?
|
|
690
|
-
├──
|
|
815
|
+
├── 20 checks in parallel (incl. deep injection + deep auth)
|
|
691
816
|
├── apply exceptions from .mcp/exceptions/
|
|
692
817
|
├── compute confidence score
|
|
693
818
|
└── returns PASS/FAIL + findings[]
|
|
@@ -695,6 +820,8 @@ User: /senior-security-engineer
|
|
|
695
820
|
▼
|
|
696
821
|
Claude writes inline fixes for every finding
|
|
697
822
|
(production-ready secure code, not suggestions)
|
|
823
|
+
Every HIGH/CRITICAL: FIXED with verified-clean re-run,
|
|
824
|
+
OR formally blocked with risk-acceptance record
|
|
698
825
|
│
|
|
699
826
|
▼
|
|
700
827
|
security.attest_review(runId)
|
|
@@ -702,7 +829,7 @@ User: /senior-security-engineer
|
|
|
702
829
|
└── SHA-256 integrity hash
|
|
703
830
|
```
|
|
704
831
|
|
|
705
|
-
### `/ciso-orchestrator` Flow (
|
|
832
|
+
### `/ciso-orchestrator` Flow (39 Agents)
|
|
706
833
|
|
|
707
834
|
```text
|
|
708
835
|
User: /ciso-orchestrator
|
|
@@ -716,7 +843,7 @@ User: /ciso-orchestrator
|
|
|
716
843
|
│ -> stackContext: { languages, frameworks, cloudProvider, hasAI, hasMobile, ... }
|
|
717
844
|
├── security.start_review() -> runId
|
|
718
845
|
├── orchestration.create_agent_run() -> agentRunId + manifest.json
|
|
719
|
-
└── orchestration.ensure_skill(
|
|
846
|
+
└── orchestration.ensure_skill(×N) -> download stack-relevant skills from 86-skill registry
|
|
720
847
|
│
|
|
721
848
|
▼
|
|
722
849
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
@@ -853,7 +980,7 @@ Your AI uses these automatically. You don't call them directly, but understandin
|
|
|
853
980
|
| Tool | What It Does |
|
|
854
981
|
| --- | --- |
|
|
855
982
|
| `security.start_review` | Starts a stateful review run; returns `runId` used to track all subsequent steps and produce the final attestation |
|
|
856
|
-
| `security.run_pr_gate` | Runs
|
|
983
|
+
| `security.run_pr_gate` | Runs 20 security checks in parallel; returns PASS/FAIL, findings with severity, and required actions |
|
|
857
984
|
| `security.threat_model` | Generates a STRIDE + PASTA + ATT&CK threat model template for a specific feature or surface |
|
|
858
985
|
| `security.checklist` | Returns the pre-release security checklist, optionally filtered by surface (web / api / mobile / ai / infra / payments) |
|
|
859
986
|
| `security.scan_strategy` | Builds an exhaustive scan plan mapping every check to OWASP, NIST, ATT&CK, and compliance controls |
|
|
@@ -544,6 +544,206 @@
|
|
|
544
544
|
"surfaces": ["all"],
|
|
545
545
|
"frameworks": ["GDPR", "HIPAA", "PCI DSS 4.0"],
|
|
546
546
|
"required_scanners": ["semgrep"]
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
"id": "OAUTH_PKCE_ENFORCED",
|
|
550
|
+
"description": "All OAuth 2.0 public clients use PKCE with S256 code challenge method.",
|
|
551
|
+
"automation": "tooling",
|
|
552
|
+
"surfaces": ["web", "api", "mobile"],
|
|
553
|
+
"frameworks": ["RFC 7636", "OWASP ASVS 3.5.3"],
|
|
554
|
+
"required_scanners": ["semgrep"]
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
"id": "JWT_ALG_CONFUSION_PREVENTED",
|
|
558
|
+
"description": "All jwt.verify() calls pin the algorithm to RS256/ES256 — algorithm confusion attack prevented.",
|
|
559
|
+
"automation": "tooling",
|
|
560
|
+
"surfaces": ["web", "api"],
|
|
561
|
+
"frameworks": ["CWE-327", "OWASP A07"],
|
|
562
|
+
"required_scanners": ["semgrep"]
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
"id": "SESSION_FIXATION_PREVENTED",
|
|
566
|
+
"description": "Session is regenerated after authentication to prevent session fixation attacks.",
|
|
567
|
+
"automation": "tooling",
|
|
568
|
+
"surfaces": ["web", "api"],
|
|
569
|
+
"frameworks": ["CWE-384", "OWASP A07"],
|
|
570
|
+
"required_scanners": ["semgrep"]
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
"id": "BUSINESS_LOGIC_REVIEWED",
|
|
574
|
+
"description": "Business logic abuse scenarios (state skipping, negative values, race conditions) are tested before release.",
|
|
575
|
+
"automation": "evidence",
|
|
576
|
+
"surfaces": ["all"],
|
|
577
|
+
"frameworks": ["OWASP Testing Guide OTG-BUSLOGIC", "NIST SP 800-53 SA-11"],
|
|
578
|
+
"evidence": ["pentest-report.json", "threat-model.json"]
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
"id": "RACE_CONDITION_MITIGATED",
|
|
582
|
+
"description": "All limit-once invariants (balance, quota, inventory, coupons) are protected by atomic DB operations.",
|
|
583
|
+
"automation": "tooling",
|
|
584
|
+
"surfaces": ["api"],
|
|
585
|
+
"frameworks": ["CWE-362", "OWASP Testing Guide OTG-BUSLOGIC-009"],
|
|
586
|
+
"required_scanners": ["semgrep"]
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
"id": "PROTOTYPE_POLLUTION_MITIGATED",
|
|
590
|
+
"description": "All object merges of user-controlled data are protected by schema validation before merge.",
|
|
591
|
+
"automation": "tooling",
|
|
592
|
+
"surfaces": ["web", "api"],
|
|
593
|
+
"frameworks": ["CWE-1321", "OWASP A03"],
|
|
594
|
+
"required_scanners": ["semgrep"]
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
"id": "HTTP_SMUGGLING_MITIGATED",
|
|
598
|
+
"description": "Proxy and origin servers normalize CL/TE headers; H2C upgrade disabled.",
|
|
599
|
+
"automation": "evidence",
|
|
600
|
+
"surfaces": ["web", "api"],
|
|
601
|
+
"frameworks": ["CWE-444", "OWASP Testing Guide OTG-INPVAL-016"],
|
|
602
|
+
"evidence": ["pentest-report.json"]
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
"id": "XXE_PREVENTED",
|
|
606
|
+
"description": "XML parsers disable external entity processing (processEntities:false).",
|
|
607
|
+
"automation": "tooling",
|
|
608
|
+
"surfaces": ["api"],
|
|
609
|
+
"frameworks": ["CWE-611", "OWASP A03"],
|
|
610
|
+
"required_scanners": ["semgrep"]
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
"id": "SSTI_PREVENTED",
|
|
614
|
+
"description": "Server-side templates are never compiled from user-controlled input.",
|
|
615
|
+
"automation": "tooling",
|
|
616
|
+
"surfaces": ["web", "api"],
|
|
617
|
+
"frameworks": ["CWE-94", "OWASP A03"],
|
|
618
|
+
"required_scanners": ["semgrep"]
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
"id": "DESERIALIZATION_SAFE",
|
|
622
|
+
"description": "Untrusted data is never passed to unsafe deserialization functions (node-serialize, eval, new Function).",
|
|
623
|
+
"automation": "tooling",
|
|
624
|
+
"surfaces": ["api"],
|
|
625
|
+
"frameworks": ["CWE-502", "OWASP A08"],
|
|
626
|
+
"required_scanners": ["semgrep"]
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
"id": "NOSQL_INJECTION_PREVENTED",
|
|
630
|
+
"description": "MongoDB/DynamoDB queries are built from validated fields, not raw user input.",
|
|
631
|
+
"automation": "tooling",
|
|
632
|
+
"surfaces": ["api"],
|
|
633
|
+
"frameworks": ["CWE-943", "OWASP A03"],
|
|
634
|
+
"required_scanners": ["semgrep"]
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
"id": "HTTP_VERB_TAMPERING_PREVENTED",
|
|
638
|
+
"description": "Read-only endpoints return 405 on PUT/DELETE — HTTP verb tampering blocked.",
|
|
639
|
+
"automation": "tooling",
|
|
640
|
+
"surfaces": ["api"],
|
|
641
|
+
"frameworks": ["OWASP Testing Guide OTG-INPVAL-003"],
|
|
642
|
+
"required_scanners": ["semgrep"]
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
"id": "OPEN_REDIRECT_BLOCKED",
|
|
646
|
+
"description": "All res.redirect() targets are validated against an allowlist or enforced relative-only.",
|
|
647
|
+
"automation": "tooling",
|
|
648
|
+
"surfaces": ["web", "api"],
|
|
649
|
+
"frameworks": ["CWE-601", "OWASP A01"],
|
|
650
|
+
"required_scanners": ["semgrep"]
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
"id": "SUBDOMAIN_TAKEOVER_MITIGATED",
|
|
654
|
+
"description": "DNS audit confirms no dangling CNAME records pointing to unprovisioned services.",
|
|
655
|
+
"automation": "evidence",
|
|
656
|
+
"surfaces": ["web"],
|
|
657
|
+
"frameworks": ["OWASP Testing Guide OTG-CONFIG-010"],
|
|
658
|
+
"evidence": ["dns-audit.json"]
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
"id": "GRAPHQL_FULL_HARDENING",
|
|
662
|
+
"description": "GraphQL introspection disabled, depth/complexity limits enforced, batching limited, field-level auth present.",
|
|
663
|
+
"automation": "tooling",
|
|
664
|
+
"surfaces": ["api"],
|
|
665
|
+
"frameworks": ["OWASP API Security Top 10", "OWASP Testing Guide"],
|
|
666
|
+
"required_scanners": ["semgrep"]
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"id": "AI_MULTIMODAL_INJECTION_PREVENTED",
|
|
670
|
+
"description": "Multimodal inputs (image, audio, document) are treated as untrusted and cannot inject instructions.",
|
|
671
|
+
"automation": "evidence",
|
|
672
|
+
"surfaces": ["ai"],
|
|
673
|
+
"frameworks": ["OWASP LLM01", "MITRE ATLAS AML.T0054"],
|
|
674
|
+
"evidence": ["ai-redteam-report.json"]
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
"id": "AI_MEMORY_POISONING_PREVENTED",
|
|
678
|
+
"description": "Agent memory and scratchpad content is validated before use in downstream instructions.",
|
|
679
|
+
"automation": "evidence",
|
|
680
|
+
"surfaces": ["ai"],
|
|
681
|
+
"frameworks": ["OWASP LLM08", "MITRE ATLAS"],
|
|
682
|
+
"evidence": ["ai-redteam-report.json"]
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
"id": "AI_MODEL_INVERSION_MITIGATED",
|
|
686
|
+
"description": "Model cannot be probed to recite training PII or memorized secrets.",
|
|
687
|
+
"automation": "evidence",
|
|
688
|
+
"surfaces": ["ai"],
|
|
689
|
+
"frameworks": ["OWASP LLM06", "MITRE ATLAS AML.T0057"],
|
|
690
|
+
"evidence": ["ai-redteam-report.json"]
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
"id": "MASVS_ANTI_REVERSING",
|
|
694
|
+
"description": "Mobile release binary uses code obfuscation and anti-instrumentation controls (MASVS-RESILIENCE).",
|
|
695
|
+
"automation": "evidence",
|
|
696
|
+
"surfaces": ["mobile"],
|
|
697
|
+
"frameworks": ["OWASP MASVS 2.0 RESILIENCE"],
|
|
698
|
+
"evidence": ["mobile-binary-review.json"]
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
"id": "IMDS_V2_ENFORCED",
|
|
702
|
+
"description": "EC2 instances enforce IMDSv2 (HttpTokens=required) — IMDSv1 disabled.",
|
|
703
|
+
"automation": "tooling",
|
|
704
|
+
"surfaces": ["infra"],
|
|
705
|
+
"frameworks": ["CIS AWS Foundations Benchmark 5.6", "NIST SP 800-53 SC-7"],
|
|
706
|
+
"required_scanners": ["checkov"]
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
"id": "CLOUD_THREAT_DETECTION_ENABLED",
|
|
710
|
+
"description": "AWS GuardDuty / GCP SCC / Azure Defender for Cloud is enabled across all accounts.",
|
|
711
|
+
"automation": "tooling",
|
|
712
|
+
"surfaces": ["infra"],
|
|
713
|
+
"frameworks": ["CIS Benchmark", "NIST SP 800-53 SI-3"],
|
|
714
|
+
"required_scanners": ["checkov"]
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
"id": "MAGECART_PROTECTION",
|
|
718
|
+
"description": "Payment pages enforce extra-strict CSP and SRI on all scripts — Magecart e-skimming prevented.",
|
|
719
|
+
"automation": "tooling",
|
|
720
|
+
"surfaces": ["payments", "web"],
|
|
721
|
+
"frameworks": ["PCI DSS 4.0 Req 6.4.3", "OWASP ASVS 14.4"],
|
|
722
|
+
"required_scanners": ["semgrep"]
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"id": "PCI_3DS_V2_ENFORCED",
|
|
726
|
+
"description": "EMV 3DS version 2.2+ is used for all card-not-present high-risk transactions.",
|
|
727
|
+
"automation": "evidence",
|
|
728
|
+
"surfaces": ["payments"],
|
|
729
|
+
"frameworks": ["PCI DSS 4.0 Req 8", "EMV 3DS 2.2"],
|
|
730
|
+
"evidence": ["payment-integration-test-results.json"]
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
"id": "HIPAA_PHI_CONTROLS",
|
|
734
|
+
"description": "Protected Health Information (PHI) is encrypted at rest and in transit; access is limited and audited.",
|
|
735
|
+
"automation": "evidence",
|
|
736
|
+
"surfaces": ["all"],
|
|
737
|
+
"frameworks": ["HIPAA §164.312", "NIST SP 800-53 SC-28"],
|
|
738
|
+
"evidence": ["hipaa-phi-audit.json"]
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
"id": "SUPPLY_CHAIN_CICD_HARDENED",
|
|
742
|
+
"description": "All CI/CD GitHub Actions are SHA-pinned; GITHUB_TOKEN has minimal permissions; no pwn-request risk.",
|
|
743
|
+
"automation": "tooling",
|
|
744
|
+
"surfaces": ["infra"],
|
|
745
|
+
"frameworks": ["SLSA Level 3", "NIST SP 800-161", "CIS Software Supply Chain Benchmark"],
|
|
746
|
+
"required_scanners": ["semgrep", "checkov"]
|
|
547
747
|
}
|
|
548
748
|
]
|
|
549
749
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
* --version
|
|
10
10
|
* --help
|
|
11
11
|
*/
|
|
12
|
-
import { createRequire } from "module";
|
|
13
|
-
import { fileURLToPath } from "url";
|
|
14
|
-
import { dirname, resolve } from "path";
|
|
12
|
+
import { createRequire } from "node:module";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { dirname, resolve } from "node:path";
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import { homedir, platform } from "node:os";
|
|
15
17
|
import { runInstall } from "./install.js";
|
|
16
18
|
import { main as runServer } from "../mcp/server.js";
|
|
17
19
|
import { notifyIfUpdateAvailable } from "./update.js";
|
|
@@ -55,6 +57,7 @@ COMMANDS
|
|
|
55
57
|
install Auto-detect installed editors and write MCP configs
|
|
56
58
|
install-global Install using the globally installed security-mcp binary
|
|
57
59
|
config Print MCP config JSON for manual editor setup
|
|
60
|
+
doctor Verify the installation is working correctly
|
|
58
61
|
|
|
59
62
|
OPTIONS (install)
|
|
60
63
|
--claude-code Write config for Claude Code only
|
|
@@ -87,6 +90,9 @@ EXAMPLES
|
|
|
87
90
|
# Preview install without writing:
|
|
88
91
|
npx -y security-mcp@latest install --dry-run
|
|
89
92
|
|
|
93
|
+
# Verify installation health:
|
|
94
|
+
npx -y security-mcp@latest doctor
|
|
95
|
+
|
|
90
96
|
# Print JSON config snippet:
|
|
91
97
|
npx -y security-mcp@latest config
|
|
92
98
|
security-mcp config --use-global-binary
|
|
@@ -103,11 +109,76 @@ EDITOR CONFIG (add manually if install fails):
|
|
|
103
109
|
|
|
104
110
|
Claude Code: ~/.claude/settings.json
|
|
105
111
|
Cursor: ~/.cursor/mcp.json or .cursor/mcp.json
|
|
106
|
-
VS Code: .
|
|
112
|
+
VS Code: User settings.json (via Preferences > Open User Settings JSON)
|
|
113
|
+
Windsurf: ~/.windsurf/mcp.json
|
|
107
114
|
|
|
108
115
|
MORE INFO
|
|
109
116
|
https://github.com/AbrahamOO/security-mcp
|
|
110
117
|
`;
|
|
118
|
+
function resolveHome(p) {
|
|
119
|
+
return p.replace(/^~/, homedir());
|
|
120
|
+
}
|
|
121
|
+
function getVsCodeSettingsPath() {
|
|
122
|
+
const os = platform();
|
|
123
|
+
if (os === "win32")
|
|
124
|
+
return `${process.env["APPDATA"] ?? ""}\\Code\\User\\settings.json`;
|
|
125
|
+
if (os === "darwin")
|
|
126
|
+
return `${homedir()}/Library/Application Support/Code/User/settings.json`;
|
|
127
|
+
return `${homedir()}/.config/Code/User/settings.json`;
|
|
128
|
+
}
|
|
129
|
+
function runDoctor() {
|
|
130
|
+
const checks = [];
|
|
131
|
+
// Node.js version
|
|
132
|
+
const nodeVer = process.versions.node.split(".").map(Number);
|
|
133
|
+
const nodeOk = (nodeVer[0] ?? 0) >= 20;
|
|
134
|
+
checks.push({ label: `Node.js ${process.versions.node}`, ok: nodeOk, hint: nodeOk ? undefined : "Node.js 20+ required. Download from https://nodejs.org" });
|
|
135
|
+
// Claude Code config
|
|
136
|
+
const claudeConfig = resolveHome("~/.claude/settings.json");
|
|
137
|
+
const claudeOk = existsSync(claudeConfig);
|
|
138
|
+
checks.push({ label: `Claude Code config (${claudeConfig})`, ok: claudeOk, hint: claudeOk ? undefined : "Run: npx -y security-mcp@latest install --claude-code" });
|
|
139
|
+
// Claude Code skill
|
|
140
|
+
const skillPath = resolveHome("~/.claude/skills/senior-security-engineer/SKILL.md");
|
|
141
|
+
const skillOk = existsSync(skillPath);
|
|
142
|
+
checks.push({ label: `senior-security-engineer skill (${skillPath})`, ok: skillOk, hint: skillOk ? undefined : "Run: npx -y security-mcp@latest install --claude-code" });
|
|
143
|
+
// Cursor global config
|
|
144
|
+
const cursorConfig = resolveHome("~/.cursor/mcp.json");
|
|
145
|
+
if (existsSync(resolveHome("~/.cursor"))) {
|
|
146
|
+
const cursorOk = existsSync(cursorConfig);
|
|
147
|
+
checks.push({ label: `Cursor config (${cursorConfig})`, ok: cursorOk, hint: cursorOk ? undefined : "Run: npx -y security-mcp@latest install --cursor" });
|
|
148
|
+
}
|
|
149
|
+
// VS Code config
|
|
150
|
+
const vscodePath = getVsCodeSettingsPath();
|
|
151
|
+
if (existsSync(vscodePath)) {
|
|
152
|
+
checks.push({ label: `VS Code config (${vscodePath})`, ok: true });
|
|
153
|
+
}
|
|
154
|
+
// Windsurf config
|
|
155
|
+
const windsurfConfig = resolveHome("~/.windsurf/mcp.json");
|
|
156
|
+
if (existsSync(resolveHome("~/.windsurf"))) {
|
|
157
|
+
const windsurfOk = existsSync(windsurfConfig);
|
|
158
|
+
checks.push({ label: `Windsurf config (${windsurfConfig})`, ok: windsurfOk, hint: windsurfOk ? undefined : "Run: npx -y security-mcp@latest install" });
|
|
159
|
+
}
|
|
160
|
+
process.stdout.write(`\nsecurity-mcp doctor v${VERSION}\n`);
|
|
161
|
+
process.stdout.write("=".repeat(40) + "\n\n");
|
|
162
|
+
let allOk = true;
|
|
163
|
+
for (const check of checks) {
|
|
164
|
+
const status = check.ok ? "PASS" : "FAIL";
|
|
165
|
+
process.stdout.write(` [${status}] ${check.label}\n`);
|
|
166
|
+
if (!check.ok) {
|
|
167
|
+
allOk = false;
|
|
168
|
+
if (check.hint)
|
|
169
|
+
process.stdout.write(` Fix: ${check.hint}\n`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
process.stdout.write("\n");
|
|
173
|
+
if (allOk) {
|
|
174
|
+
process.stdout.write("All checks passed. security-mcp is installed correctly.\n");
|
|
175
|
+
process.stdout.write("Restart your editor if you haven't already, then type /senior-security-engineer.\n\n");
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
process.stdout.write("Some checks failed. Run the suggested fix commands above, then re-run: npx -y security-mcp@latest doctor\n\n");
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
111
182
|
async function main() {
|
|
112
183
|
const args = process.argv.slice(2);
|
|
113
184
|
const useGlobalBinary = args.includes("--use-global-binary");
|
|
@@ -165,7 +236,13 @@ async function main() {
|
|
|
165
236
|
process.stdout.write("\nAdd the above to your editor's MCP config file.\n");
|
|
166
237
|
process.stdout.write(" Claude Code: ~/.claude/settings.json\n");
|
|
167
238
|
process.stdout.write(" Cursor: ~/.cursor/mcp.json\n");
|
|
168
|
-
process.stdout.write(" VS Code: .
|
|
239
|
+
process.stdout.write(" VS Code: User settings.json (Preferences > Open User Settings JSON)\n");
|
|
240
|
+
process.stdout.write(" Windsurf: ~/.windsurf/mcp.json\n");
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
case "doctor":
|
|
244
|
+
case "verify": {
|
|
245
|
+
runDoctor();
|
|
169
246
|
break;
|
|
170
247
|
}
|
|
171
248
|
default: {
|