security-mcp 1.1.3 → 1.3.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.
Files changed (133) hide show
  1. package/README.md +164 -185
  2. package/defaults/checklists/ai.json +20 -1
  3. package/defaults/checklists/api.json +35 -1
  4. package/defaults/checklists/infra.json +34 -1
  5. package/defaults/checklists/mobile.json +23 -1
  6. package/defaults/checklists/payments.json +15 -1
  7. package/defaults/checklists/web.json +11 -1
  8. package/defaults/control-catalog.json +200 -0
  9. package/defaults/security-policy.json +2 -2
  10. package/dist/cli/index.js +82 -5
  11. package/dist/cli/install.js +36 -6
  12. package/dist/cli/onboarding.js +6 -0
  13. package/dist/gate/baseline.js +82 -7
  14. package/dist/gate/catalog.js +10 -2
  15. package/dist/gate/checks/ai.js +757 -39
  16. package/dist/gate/checks/auth-deep.js +935 -0
  17. package/dist/gate/checks/business-logic.js +751 -0
  18. package/dist/gate/checks/ci-pipeline.js +399 -4
  19. package/dist/gate/checks/crypto.js +423 -2
  20. package/dist/gate/checks/dependencies.js +571 -15
  21. package/dist/gate/checks/graphql.js +201 -19
  22. package/dist/gate/checks/infra.js +246 -1
  23. package/dist/gate/checks/injection-deep.js +848 -0
  24. package/dist/gate/checks/k8s.js +114 -1
  25. package/dist/gate/checks/mobile-android.js +917 -3
  26. package/dist/gate/checks/mobile-ios.js +797 -5
  27. package/dist/gate/checks/required-artifacts.js +194 -0
  28. package/dist/gate/checks/runtime.js +178 -0
  29. package/dist/gate/checks/secrets.js +244 -13
  30. package/dist/gate/checks/supply-chain-deep.js +787 -0
  31. package/dist/gate/checks/web-nextjs.js +572 -48
  32. package/dist/gate/diff.js +17 -5
  33. package/dist/gate/evidence.js +8 -1
  34. package/dist/gate/exceptions.js +131 -9
  35. package/dist/gate/policy.js +282 -129
  36. package/dist/mcp/audit-chain.js +122 -28
  37. package/dist/mcp/auth.js +169 -0
  38. package/dist/mcp/learning.js +129 -4
  39. package/dist/mcp/model-router.js +158 -21
  40. package/dist/mcp/orchestration.js +186 -51
  41. package/dist/mcp/server.js +608 -94
  42. package/dist/repo/fs.js +24 -1
  43. package/dist/repo/search.js +31 -6
  44. package/dist/review/store.js +52 -1
  45. package/package.json +7 -7
  46. package/prompts/SECURITY_PROMPT.md +73 -0
  47. package/skills/_TEMPLATE/SKILL.md +99 -0
  48. package/skills/advanced-dos-tester/SKILL.md +109 -0
  49. package/skills/agentic-loop-exploiter/SKILL.md +368 -0
  50. package/skills/ai-llm-redteam/SKILL.md +104 -0
  51. package/skills/ai-model-supply-chain-agent/SKILL.md +103 -0
  52. package/skills/algorithm-implementation-reviewer/SKILL.md +98 -0
  53. package/skills/android-penetration-tester/SKILL.md +455 -46
  54. package/skills/anti-replay-tester/SKILL.md +106 -0
  55. package/skills/appsec-code-auditor/SKILL.md +120 -0
  56. package/skills/artifact-integrity-analyst/SKILL.md +441 -0
  57. package/skills/attack-navigator/SKILL.md +467 -8
  58. package/skills/auth-session-hacker/SKILL.md +128 -0
  59. package/skills/aws-penetration-tester/SKILL.md +456 -0
  60. package/skills/azure-penetration-tester/SKILL.md +490 -3
  61. package/skills/binary-auth-validator/SKILL.md +111 -0
  62. package/skills/bot-detection-specialist/SKILL.md +109 -0
  63. package/skills/business-logic-attacker/SKILL.md +231 -0
  64. package/skills/capec-code-mapper/SKILL.md +84 -0
  65. package/skills/cert-pin-rotation-specialist/SKILL.md +112 -0
  66. package/skills/cicd-pipeline-hijacker/SKILL.md +405 -0
  67. package/skills/ciso-orchestrator/SKILL.md +454 -43
  68. package/skills/cloud-infra-specialist/SKILL.md +118 -0
  69. package/skills/compliance-gap-analyst/SKILL.md +422 -0
  70. package/skills/compliance-grc/SKILL.md +85 -0
  71. package/skills/compliance-lifecycle-tracker/SKILL.md +84 -0
  72. package/skills/credential-stuffing-specialist/SKILL.md +102 -0
  73. package/skills/crypto-pki-specialist/SKILL.md +87 -0
  74. package/skills/csa-ccm-mapper/SKILL.md +84 -0
  75. package/skills/csf2-governance-mapper/SKILL.md +84 -0
  76. package/skills/deep-link-fuzzer/SKILL.md +109 -0
  77. package/skills/dependency-confusion-attacker/SKILL.md +415 -0
  78. package/skills/device-integrity-aggregator/SKILL.md +108 -0
  79. package/skills/dos-resilience-tester/SKILL.md +97 -0
  80. package/skills/dread-scorer/SKILL.md +84 -0
  81. package/skills/egress-policy-enforcer/SKILL.md +99 -0
  82. package/skills/evidence-collector/SKILL.md +98 -0
  83. package/skills/file-upload-attacker/SKILL.md +109 -0
  84. package/skills/gcp-penetration-tester/SKILL.md +459 -2
  85. package/skills/git-history-secret-scanner/SKILL.md +106 -0
  86. package/skills/iam-privesc-graph-builder/SKILL.md +152 -0
  87. package/skills/incident-responder/SKILL.md +111 -0
  88. package/skills/injection-specialist/SKILL.md +131 -0
  89. package/skills/ios-security-auditor/SKILL.md +282 -0
  90. package/skills/json-ambiguity-tester/SKILL.md +0 -0
  91. package/skills/k8s-container-escaper/SKILL.md +384 -0
  92. package/skills/key-management-lifecycle-analyst/SKILL.md +98 -0
  93. package/skills/kill-switch-engineer/SKILL.md +102 -0
  94. package/skills/linddun-privacy-analyst/SKILL.md +102 -0
  95. package/skills/logic-race-fuzzer/SKILL.md +443 -0
  96. package/skills/mobile-api-network-attacker/SKILL.md +421 -0
  97. package/skills/mobile-binary-hardener/SKILL.md +102 -0
  98. package/skills/mobile-security-specialist/SKILL.md +85 -0
  99. package/skills/mobile-webview-auditor/SKILL.md +96 -0
  100. package/skills/model-extraction-attacker/SKILL.md +219 -0
  101. package/skills/multipart-abuse-tester/SKILL.md +84 -0
  102. package/skills/oauth-pkce-specialist/SKILL.md +104 -0
  103. package/skills/parser-exhaustion-tester/SKILL.md +142 -0
  104. package/skills/pentest-infra/SKILL.md +141 -0
  105. package/skills/pentest-social/SKILL.md +201 -0
  106. package/skills/pentest-team/SKILL.md +134 -0
  107. package/skills/pentest-web-api/SKILL.md +151 -0
  108. package/skills/privacy-flow-analyst/SKILL.md +234 -0
  109. package/skills/prompt-injection-specialist/SKILL.md +394 -0
  110. package/skills/quantum-migration-planner/SKILL.md +96 -0
  111. package/skills/rag-poisoning-specialist/SKILL.md +358 -0
  112. package/skills/registry-mirror-enforcer/SKILL.md +84 -0
  113. package/skills/rotation-validation-agent/SKILL.md +112 -0
  114. package/skills/samm-assessor/SKILL.md +85 -0
  115. package/skills/secrets-mask-bypass-tester/SKILL.md +100 -0
  116. package/skills/senior-security-engineer/SKILL.md +370 -2
  117. package/skills/serialization-memory-attacker/SKILL.md +332 -0
  118. package/skills/session-timeout-tester/SKILL.md +161 -0
  119. package/skills/slsa-level3-enforcer/SKILL.md +112 -0
  120. package/skills/slsa-provenance-enforcer/SKILL.md +102 -0
  121. package/skills/ssrf-detection-validator/SKILL.md +108 -0
  122. package/skills/step-up-auth-enforcer/SKILL.md +84 -0
  123. package/skills/stride-pasta-analyst/SKILL.md +420 -0
  124. package/skills/supply-chain-devsecops/SKILL.md +98 -0
  125. package/skills/threat-infrastructure-analyst/SKILL.md +84 -0
  126. package/skills/threat-modeler/SKILL.md +85 -0
  127. package/skills/tls-certificate-auditor/SKILL.md +573 -18
  128. package/skills/token-reuse-detector/SKILL.md +95 -0
  129. package/skills/trike-risk-modeler/SKILL.md +84 -0
  130. package/skills/unicode-homograph-tester/SKILL.md +84 -0
  131. package/skills/waf-rule-lifecycle-agent/SKILL.md +97 -0
  132. package/skills/webhook-security-tester/SKILL.md +102 -0
  133. package/skills/zero-trust-architect/SKILL.md +109 -0
@@ -98,6 +98,34 @@ function checkContainerSecurity(ctx) {
98
98
  ]
99
99
  });
100
100
  }
101
+ const runsAsRootFiles = matching(ctx, /runAsUser:\s*0/);
102
+ if (runsAsRootFiles.length > 0) {
103
+ findings.push({
104
+ id: "K8S_CONTAINER_RUNS_AS_ROOT",
105
+ title: "Container explicitly runs as root (runAsUser: 0)",
106
+ severity: "HIGH",
107
+ files: runsAsRootFiles,
108
+ requiredActions: [
109
+ "Container explicitly runs as root (runAsUser: 0) — container escape yields immediate host root.",
110
+ "Set runAsNonRoot: true and use a non-zero runAsUser UID (e.g. 1000) in all container securityContexts."
111
+ ]
112
+ });
113
+ }
114
+ // Use /capabilities:/ as the anchor so pod-level securityContext (which has no capabilities)
115
+ // doesn't cause a false positive, and YAML comments don't trigger a match.
116
+ const capsNotDroppedFiles = filterFiles(ctx, (c) => /capabilities:/.test(c) && !/drop:/.test(c));
117
+ if (capsNotDroppedFiles.length > 0) {
118
+ findings.push({
119
+ id: "K8S_CAPABILITIES_NOT_DROPPED",
120
+ title: "Container capabilities not dropped",
121
+ severity: "HIGH",
122
+ files: capsNotDroppedFiles,
123
+ requiredActions: [
124
+ "Container capabilities not dropped — NET_RAW/SYS_PTRACE available for host attacks.",
125
+ "Add capabilities.drop: [ALL] to all container securityContexts and explicitly re-add only required capabilities."
126
+ ]
127
+ });
128
+ }
101
129
  return findings;
102
130
  }
103
131
  function checkRbacAndConfig(ctx) {
@@ -168,11 +196,93 @@ function checkRbacAndConfig(ctx) {
168
196
  ]
169
197
  });
170
198
  }
199
+ const nodePortFiles = matching(ctx, /type:\s*NodePort/);
200
+ if (nodePortFiles.length > 0) {
201
+ findings.push({
202
+ id: "K8S_NODEPORT_EXPOSURE",
203
+ title: "Kubernetes NodePort service detected",
204
+ severity: "MEDIUM",
205
+ files: nodePortFiles,
206
+ requiredActions: [
207
+ "Kubernetes NodePort service detected — service exposed on every node's public IP, bypasses WAF.",
208
+ "Replace NodePort services with LoadBalancer or Ingress resources fronted by a WAF/API gateway."
209
+ ]
210
+ });
211
+ }
212
+ // Also match YAML-quoted forms: anonymous-auth: 'true' and anonymous-auth: "true"
213
+ const anonAuthFiles = matching(ctx, /--anonymous-auth=true|anonymous-auth:\s*['"]?true['"]?/);
214
+ if (anonAuthFiles.length > 0) {
215
+ findings.push({
216
+ id: "K8S_API_ANONYMOUS_AUTH",
217
+ title: "Kubernetes API server has --anonymous-auth=true",
218
+ severity: "CRITICAL",
219
+ files: anonAuthFiles,
220
+ requiredActions: [
221
+ "Kubernetes API server has --anonymous-auth=true — unauthenticated requests processed as system:anonymous.",
222
+ "Set --anonymous-auth=false in the kube-apiserver configuration and remove any ClusterRoleBindings for system:anonymous."
223
+ ]
224
+ });
225
+ }
226
+ return findings;
227
+ }
228
+ function checkDockerSocketMount(ctx) {
229
+ const findings = [];
230
+ const dockerSocketFiles = matching(ctx, /\/var\/run\/docker\.sock/);
231
+ if (dockerSocketFiles.length > 0) {
232
+ findings.push({
233
+ id: "K8S_DOCKER_SOCKET_MOUNT",
234
+ title: "Docker socket mounted inside Kubernetes pod",
235
+ severity: "CRITICAL",
236
+ files: dockerSocketFiles,
237
+ requiredActions: [
238
+ "Docker socket mounted inside Kubernetes pod — container controls host Docker daemon, trivial escape to root.",
239
+ "Remove /var/run/docker.sock volume mounts. Use a dedicated sidecar image builder (e.g. Kaniko, Buildah) or an in-cluster container registry instead."
240
+ ]
241
+ });
242
+ }
243
+ return findings;
244
+ }
245
+ function checkTillerHelm(ctx) {
246
+ const findings = [];
247
+ const tillerFiles = matching(ctx, /tiller-deploy|gcr\.io\/kubernetes-helm\/tiller/);
248
+ if (tillerFiles.length > 0) {
249
+ findings.push({
250
+ id: "K8S_TILLER_HELM_V2",
251
+ title: "Helm v2 Tiller detected",
252
+ severity: "CRITICAL",
253
+ files: tillerFiles,
254
+ requiredActions: [
255
+ "Helm v2 Tiller detected — unauthenticated cluster-admin gRPC endpoint inside cluster.",
256
+ "Migrate to Helm v3 which eliminates Tiller entirely. Remove all tiller-deploy Deployments and ServiceAccounts."
257
+ ]
258
+ });
259
+ }
260
+ return findings;
261
+ }
262
+ function checkMtlsPolicy(ctx) {
263
+ const findings = [];
264
+ // PeerAuthentication is Istio-specific. Linkerd uses Server/AuthorizationPolicy CRDs
265
+ // (linkerd.io/v1alpha2) — those are not covered here.
266
+ const mtlsPermissiveFiles = filterFiles(ctx, (c) => /kind:\s*PeerAuthentication/.test(c) && /mode:\s*(?:PERMISSIVE|DISABLE)/.test(c));
267
+ if (mtlsPermissiveFiles.length > 0) {
268
+ findings.push({
269
+ id: "K8S_MTLS_NOT_STRICT",
270
+ title: "Istio PeerAuthentication in PERMISSIVE or DISABLE mode",
271
+ severity: "HIGH",
272
+ files: mtlsPermissiveFiles,
273
+ requiredActions: [
274
+ "Istio/Linkerd PeerAuthentication in PERMISSIVE or DISABLE mode — plaintext inter-service traffic allowed.",
275
+ "Set mode: STRICT in all PeerAuthentication resources to enforce mTLS for all inter-service communication."
276
+ ]
277
+ });
278
+ }
171
279
  return findings;
172
280
  }
173
281
  async function checkNetworkAndAdmission(ctx) {
174
282
  const findings = [];
175
- const networkPolicyFiles = await fg(["**/NetworkPolicy*.yaml", "**/*network-policy*.yaml", "**/NetworkPolicy*.yml", "**/*network-policy*.yml"], { ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"] });
283
+ // Filename-only glob misses NetworkPolicy manifests in files like policies.yaml;
284
+ // fall back to content-scanning already-loaded ctx files as the authoritative check.
285
+ const networkPolicyFiles = ctx.files.filter((f) => /kind:\s*NetworkPolicy/.test(ctx.contents.get(f) ?? ""));
176
286
  if (networkPolicyFiles.length === 0) {
177
287
  findings.push({
178
288
  id: "K8S_NO_NETWORK_POLICY",
@@ -228,6 +338,9 @@ export async function checkKubernetes(_opts) {
228
338
  return [
229
339
  ...checkContainerSecurity(ctx),
230
340
  ...checkRbacAndConfig(ctx),
341
+ ...checkDockerSocketMount(ctx),
342
+ ...checkTillerHelm(ctx),
343
+ ...checkMtlsPolicy(ctx),
231
344
  ...networkFindings
232
345
  ];
233
346
  }