security-mcp 1.0.5 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +963 -193
- package/defaults/agent-run-schema.json +98 -0
- package/defaults/checklists/ai.json +25 -0
- package/defaults/checklists/api.json +27 -0
- package/defaults/checklists/infra.json +27 -0
- package/defaults/checklists/mobile.json +25 -0
- package/defaults/checklists/payments.json +25 -0
- package/defaults/checklists/web.json +30 -0
- package/defaults/control-catalog.json +392 -0
- package/defaults/evidence-map.json +194 -0
- package/defaults/security-policy.json +41 -2
- package/dist/cli/index.js +13 -8
- package/dist/cli/install.js +80 -2
- package/dist/cli/onboarding.js +590 -0
- package/dist/cli/update.js +83 -15
- package/dist/gate/baseline.js +115 -0
- package/dist/gate/checks/ai-redteam.js +398 -0
- package/dist/gate/checks/api.js +93 -0
- package/dist/gate/checks/crypto.js +153 -0
- package/dist/gate/checks/database.js +144 -0
- package/dist/gate/checks/dependencies.js +126 -0
- package/dist/gate/checks/dlp.js +153 -0
- package/dist/gate/checks/graphql.js +122 -0
- package/dist/gate/checks/infra.js +126 -12
- package/dist/gate/checks/k8s.js +190 -0
- package/dist/gate/checks/playbook.js +160 -0
- package/dist/gate/checks/runtime.js +316 -0
- package/dist/gate/checks/sbom.js +199 -0
- package/dist/gate/checks/scanners.js +379 -8
- package/dist/gate/checks/secrets.js +85 -20
- package/dist/gate/exceptions.js +6 -1
- package/dist/gate/policy.js +85 -19
- package/dist/gate/threat-intel.js +157 -0
- package/dist/mcp/orchestration.js +586 -0
- package/dist/mcp/server.js +568 -16
- package/dist/repo/search.js +11 -1
- package/dist/review/store.js +133 -0
- package/dist/types/agent-run.js +8 -0
- package/package.json +5 -5
- package/prompts/SECURITY_PROMPT.md +415 -1
- package/skills/agentic-loop-exploiter/SKILL.md +69 -0
- package/skills/ai-llm-redteam/SKILL.md +118 -0
- package/skills/algorithm-implementation-reviewer/SKILL.md +85 -0
- package/skills/android-penetration-tester/SKILL.md +83 -0
- package/skills/appsec-code-auditor/SKILL.md +86 -0
- package/skills/artifact-integrity-analyst/SKILL.md +68 -0
- package/skills/attack-navigator/SKILL.md +64 -0
- package/skills/auth-session-hacker/SKILL.md +87 -0
- package/skills/aws-penetration-tester/SKILL.md +60 -0
- package/skills/azure-penetration-tester/SKILL.md +64 -0
- package/skills/business-logic-attacker/SKILL.md +76 -0
- package/skills/cicd-pipeline-hijacker/SKILL.md +81 -0
- package/skills/ciso-orchestrator/SKILL.md +165 -0
- package/skills/cloud-infra-specialist/SKILL.md +85 -0
- package/skills/compliance-gap-analyst/SKILL.md +77 -0
- package/skills/compliance-grc/SKILL.md +148 -0
- package/skills/crypto-pki-specialist/SKILL.md +136 -0
- package/skills/dependency-confusion-attacker/SKILL.md +78 -0
- package/skills/evidence-collector/SKILL.md +86 -0
- package/skills/gcp-penetration-tester/SKILL.md +63 -0
- package/skills/injection-specialist/SKILL.md +62 -0
- package/skills/ios-security-auditor/SKILL.md +77 -0
- package/skills/k8s-container-escaper/SKILL.md +74 -0
- package/skills/key-management-lifecycle-analyst/SKILL.md +92 -0
- package/skills/logic-race-fuzzer/SKILL.md +67 -0
- package/skills/mobile-api-network-attacker/SKILL.md +81 -0
- package/skills/mobile-security-specialist/SKILL.md +124 -0
- package/skills/model-extraction-attacker/SKILL.md +68 -0
- package/skills/pentest-infra/SKILL.md +69 -0
- package/skills/pentest-social/SKILL.md +72 -0
- package/skills/pentest-team/SKILL.md +126 -0
- package/skills/pentest-web-api/SKILL.md +71 -0
- package/skills/privacy-flow-analyst/SKILL.md +70 -0
- package/skills/prompt-injection-specialist/SKILL.md +76 -0
- package/skills/rag-poisoning-specialist/SKILL.md +71 -0
- package/skills/senior-security-engineer/SKILL.md +75 -13
- package/skills/serialization-memory-attacker/SKILL.md +78 -0
- package/skills/stride-pasta-analyst/SKILL.md +72 -0
- package/skills/supply-chain-devsecops/SKILL.md +82 -0
- package/skills/threat-modeler/SKILL.md +116 -0
- package/skills/tls-certificate-auditor/SKILL.md +76 -0
package/dist/cli/index.js
CHANGED
|
@@ -57,12 +57,14 @@ COMMANDS
|
|
|
57
57
|
config Print MCP config JSON for manual editor setup
|
|
58
58
|
|
|
59
59
|
OPTIONS (install)
|
|
60
|
-
--claude-code
|
|
61
|
-
--cursor
|
|
62
|
-
--vscode
|
|
63
|
-
--global
|
|
60
|
+
--claude-code Write config for Claude Code only
|
|
61
|
+
--cursor Write config for Cursor only
|
|
62
|
+
--vscode Write config for VS Code only
|
|
63
|
+
--global Write to global editor config (default)
|
|
64
64
|
--use-global-binary Write configs that execute "security-mcp serve" instead of npx
|
|
65
|
-
--dry-run
|
|
65
|
+
--dry-run Print what would change without writing
|
|
66
|
+
--yes Skip interactive setup questions (install with defaults)
|
|
67
|
+
--non-interactive Same as --yes (for CI environments)
|
|
66
68
|
|
|
67
69
|
OPTIONS (general)
|
|
68
70
|
--version Print version
|
|
@@ -131,26 +133,29 @@ async function main() {
|
|
|
131
133
|
break;
|
|
132
134
|
}
|
|
133
135
|
case "install": {
|
|
136
|
+
const noEditorFlag = !args.includes("--claude-code") && !args.includes("--cursor") && !args.includes("--vscode");
|
|
134
137
|
const options = {
|
|
135
138
|
claudeCode: args.includes("--claude-code"),
|
|
136
139
|
cursor: args.includes("--cursor"),
|
|
137
140
|
vscode: args.includes("--vscode"),
|
|
138
141
|
dryRun: args.includes("--dry-run"),
|
|
139
142
|
useGlobalBinary,
|
|
140
|
-
|
|
141
|
-
|
|
143
|
+
all: noEditorFlag,
|
|
144
|
+
interactive: !args.includes("--yes") && !args.includes("--non-interactive")
|
|
142
145
|
};
|
|
143
146
|
await runInstall(options);
|
|
144
147
|
break;
|
|
145
148
|
}
|
|
146
149
|
case "install-global": {
|
|
150
|
+
const noEditorFlag = !args.includes("--claude-code") && !args.includes("--cursor") && !args.includes("--vscode");
|
|
147
151
|
const options = {
|
|
148
152
|
claudeCode: args.includes("--claude-code"),
|
|
149
153
|
cursor: args.includes("--cursor"),
|
|
150
154
|
vscode: args.includes("--vscode"),
|
|
151
155
|
dryRun: args.includes("--dry-run"),
|
|
152
156
|
useGlobalBinary: true,
|
|
153
|
-
all:
|
|
157
|
+
all: noEditorFlag,
|
|
158
|
+
interactive: !args.includes("--yes") && !args.includes("--non-interactive")
|
|
154
159
|
};
|
|
155
160
|
await runInstall(options);
|
|
156
161
|
break;
|
package/dist/cli/install.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
import { readFileSync, writeFileSync, mkdirSync, existsSync, copyFileSync } from "node:fs";
|
|
7
7
|
import { dirname, join, resolve } from "node:path";
|
|
8
8
|
import { homedir, platform } from "node:os";
|
|
9
|
+
import * as https from "node:https";
|
|
9
10
|
import { fileURLToPath } from "node:url";
|
|
11
|
+
import { runOnboarding, installSecurityTools, commandExists, SECURITY_TOOLS } from "./onboarding.js";
|
|
10
12
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
13
|
const PKG_ROOT = resolve(__dirname, "../..");
|
|
12
14
|
function resolveHome(p) {
|
|
@@ -157,8 +159,83 @@ function installSkill(dryRun) {
|
|
|
157
159
|
}
|
|
158
160
|
process.stdout.write(` ${dryRun ? "[dry-run] would copy" : "installed"} skill: ${skillDest}\n`);
|
|
159
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Download a skill SKILL.md from a remote URL and save it to ~/.claude/skills/{skillName}/SKILL.md.
|
|
164
|
+
* Used for lazy on-demand skill installation — all sub-agents are downloaded this way at first use.
|
|
165
|
+
* Mirrors the same pattern used for security tool binary downloads in onboarding.ts.
|
|
166
|
+
*/
|
|
167
|
+
// CWE-22: only alphanumeric, hyphens, and dots allowed in skill names
|
|
168
|
+
const SAFE_SKILL_NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/;
|
|
169
|
+
export async function downloadSkill(skillName, url, dryRun = false) {
|
|
170
|
+
if (!SAFE_SKILL_NAME_RE.test(skillName)) {
|
|
171
|
+
process.stdout.write(` [error] invalid skill name "${skillName}" — skipping download\n`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const skillDest = resolveHome(`~/.claude/skills/${skillName}/SKILL.md`);
|
|
175
|
+
if (dryRun) {
|
|
176
|
+
process.stdout.write(` [dry-run] would download skill "${skillName}" from ${url} → ${skillDest}\n`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const MAX_SKILL_BYTES = 512 * 1024; // 512 KB — skills are markdown files
|
|
180
|
+
const content = await new Promise((resolve) => {
|
|
181
|
+
const req = https.get(url, { headers: { "User-Agent": "security-mcp" } }, (res) => {
|
|
182
|
+
if ((res.statusCode ?? 500) >= 400) {
|
|
183
|
+
res.resume();
|
|
184
|
+
resolve(null);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
let body = "";
|
|
188
|
+
res.setEncoding("utf8");
|
|
189
|
+
res.on("data", (chunk) => {
|
|
190
|
+
body += chunk;
|
|
191
|
+
if (Buffer.byteLength(body, "utf8") > MAX_SKILL_BYTES) {
|
|
192
|
+
req.destroy();
|
|
193
|
+
resolve(null);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
res.on("end", () => resolve(body));
|
|
197
|
+
});
|
|
198
|
+
req.on("error", () => resolve(null));
|
|
199
|
+
req.setTimeout(10000, () => { req.destroy(); resolve(null); });
|
|
200
|
+
});
|
|
201
|
+
if (!content) {
|
|
202
|
+
process.stdout.write(` [error] failed to download skill "${skillName}" from ${url}\n`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
mkdirSync(dirname(skillDest), { recursive: true });
|
|
206
|
+
writeFileSync(skillDest, content, "utf-8");
|
|
207
|
+
process.stdout.write(` installed skill: ${skillDest}\n`);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Eagerly install the orchestrator skill (bundled in the package) plus record
|
|
211
|
+
* its version so orchestration.ensure_skill can detect future updates.
|
|
212
|
+
*/
|
|
213
|
+
function installOrchestratorSkill(dryRun) {
|
|
214
|
+
const skillName = "ciso-orchestrator";
|
|
215
|
+
const skillSrc = join(PKG_ROOT, "skills", skillName, "SKILL.md");
|
|
216
|
+
const skillDest = resolveHome(`~/.claude/skills/${skillName}/SKILL.md`);
|
|
217
|
+
if (!existsSync(skillSrc)) {
|
|
218
|
+
process.stdout.write(` [skip] skills/${skillName}/SKILL.md not found in package\n`);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (!dryRun) {
|
|
222
|
+
mkdirSync(dirname(skillDest), { recursive: true });
|
|
223
|
+
copyFileSync(skillSrc, skillDest);
|
|
224
|
+
}
|
|
225
|
+
process.stdout.write(` ${dryRun ? "[dry-run] would copy" : "installed"} skill: ${skillDest}\n`);
|
|
226
|
+
}
|
|
160
227
|
export async function runInstall(opts) {
|
|
161
228
|
const dryRun = opts.dryRun;
|
|
229
|
+
// ── Interactive onboarding (skipped when --yes or non-TTY) ──────────────
|
|
230
|
+
if (opts.interactive && !dryRun) {
|
|
231
|
+
const onboarding = await runOnboarding();
|
|
232
|
+
if (onboarding?.installTools) {
|
|
233
|
+
const toInstall = SECURITY_TOOLS.filter((t) => !commandExists(t.id));
|
|
234
|
+
process.stdout.write("\nInstalling security scanning tools...\n");
|
|
235
|
+
await installSecurityTools(toInstall);
|
|
236
|
+
process.stdout.write("\n");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
162
239
|
process.stdout.write(`\nsecurity-mcp installer${dryRun ? " (dry-run)" : ""}\n`);
|
|
163
240
|
process.stdout.write("=".repeat(40) + "\n\n");
|
|
164
241
|
const targets = getEditorTargets(opts);
|
|
@@ -184,11 +261,12 @@ export async function runInstall(opts) {
|
|
|
184
261
|
process.stdout.write(` [error] ${err instanceof Error ? err.message : String(err)}\n`);
|
|
185
262
|
}
|
|
186
263
|
}
|
|
187
|
-
// Install Claude Code
|
|
264
|
+
// Install Claude Code skills if Claude Code is in scope
|
|
188
265
|
const hasClaudeCode = targets.some((t) => t.name.startsWith("Claude Code"));
|
|
189
266
|
if (hasClaudeCode || opts.all) {
|
|
190
|
-
process.stdout.write("\nInstalling Claude Code
|
|
267
|
+
process.stdout.write("\nInstalling Claude Code skills...\n");
|
|
191
268
|
installSkill(dryRun);
|
|
269
|
+
installOrchestratorSkill(dryRun);
|
|
192
270
|
}
|
|
193
271
|
process.stdout.write("\nInstalling security policy...\n");
|
|
194
272
|
installPolicy(dryRun);
|