一键导入
security-audit
Use when you want a thorough security review of the codebase, a specific file/directory, or a set of changes before shipping.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when you want a thorough security review of the codebase, a specific file/directory, or a set of changes before shipping.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when you want a thorough code review of files, changes, or the entire project before shipping.
Use when you want structured feedback on a plan or document before implementation.
Use when you want to implement the next batch of a plan. Handles module implementation, testing, and validation.
Save all session progress to status tracking files. Use when you want to checkpoint work mid-session or before ending.
| name | security-audit |
| description | Use when you want a thorough security review of the codebase, a specific file/directory, or a set of changes before shipping. |
| risk | safe |
| risk-note | audit is read-only; remediation phase applies source changes |
| argument-hint | [scope] [compliance: pci-dss|hipaa|soc2|gdpr] |
This skill must only be invoked from the main session, never from a subagent.
a. If the user specified file paths, directories, or a description of what to review, use that as the scope.
b. If the user said "review my changes" or similar, use git diff HEAD (unstaged + staged) and git diff --cached as the scope. If no changes exist, tell the user and stop.
c. If no scope is specified, ask the user: "What should I review? Options: specific files/directories, recent changes (git diff), or the entire project."
d. For entire-project scope, identify all source files (exclude vendored/generated code, build artifacts, lock files, and test fixtures). Prioritize by security relevance: route definitions, API handlers, middleware, auth modules, database access layers, and configuration files. Distribute files across agents by relevance to each agent's domain.
e. Confirm scope with the user before proceeding: "I'll security-review [scope description]. Correct?"
After determining scope, check whether the project is a web application by looking for indicators: route/endpoint definitions, HTTP framework imports (Express, Flask, Django, FastAPI, Spring, Next.js, Rails, ASP.NET, etc.), HTML templates, API handlers, or middleware. If detected, set web_app = true and inform the user: "Detected web application — enabling web-specific security checks (Agent 6)." If uncertain, ask.
Before spawning subagents, build a threat context by examining at most 10 files (entry points, configs, auth modules, route definitions):
Capture as a short bullet list (max 8 lines). If fewer than 3 relevant files are found, skip threat context generation and note "Insufficient project structure for threat modeling" in the report.
The main session must compose the relevant subset of this context into each subagent's prompt — pass trust boundaries and high-risk components to Agents 1, 2, 4, and 7; pass data sensitivity to Agents 3 and 5; pass all three to Agent 6 (if active). Follow the same pattern as web_app conditionals: inline the context directly, do not use placeholder variables.
Check for IaC files: *.tf (Terraform), CloudFormation templates (AWSTemplateFormatVersion), Pulumi.yaml, Kubernetes manifests (files containing both apiVersion: and kind: where kind matches a known K8s resource — Pod, Deployment, Service, StatefulSet, Ingress, ConfigMap, Secret, etc. — or files co-located with kustomization.yaml), Helm charts (Chart.yaml). If found, set iac_detected = true and inform user: "Detected IaC files ([tool]) — enabling infrastructure configuration checks in Agent 4."
Check for .php files or composer.json in scope. If found, set php_detected = true and inform user: "Detected PHP project — enabling PHP-specific security checks in Agent 1."
If the user includes compliance: <framework> in their arguments (e.g., /security-audit src/ compliance: hipaa), set compliance_framework and confirm with the user. If the user mentions compliance in natural language (e.g., "we need HIPAA compliance"), infer the framework but always confirm before enabling compliance-specific checks: "I detected a reference to [framework] compliance. Should I enable [framework]-specific security checks?" Multiple frameworks can be comma-separated. Supported: pci-dss, hipaa, soc2, gdpr.
Append a compliance note to the threat context passed to each relevant agent:
Compliance scope: [framework]. Prioritize findings mapping to this framework's controls. Append control references in the Category field (e.g., "CWE-798 / PCI-DSS 2.1").
Spawn 6 subagents for all projects (Agents 1-5 and 7). If web_app = true, also spawn Agent 6 (7 total). If iac_detected = true, add up to 20 IaC files to Agent 4's scope (prioritize root modules and files containing resource/data blocks) — these must be included in the scope shown to the user in step (e) for confirmation, not added silently.
Spawn all subagents on the latest, most capable model available — omit the per-agent model override so each inherits the session's model rather than pinning a version-specific name. Do not add an override that downgrades the breadth passes (4, 5, 6, 7) to a cheaper tier such as sonnet (measured 2026-06-11: sonnet's false-positive rate in breadth slots cost more verification time than its savings), and never default any agent to haiku — these prompts require rejecting rationalizations and reading carefully, where haiku is materially weaker; use it only as an explicit opt-in after a measured comparison. (CLAUDE_CODE_SUBAGENT_MODEL, if set in the environment Claude launches subagents under, overrides the inherited model.)
For Agent 5 (secrets), always include these files in scope regardless of user-specified scope (if they exist): .env*, *.env, docker-compose*.yml, Dockerfile*, .github/workflows/*.yml, .gitlab-ci.yml, Jenkinsfile, .gitignore, .pre-commit-config.yaml, and any config files matching *config*, *settings*, *secret*. Note: Agent 5 scans CI configs for hardcoded secrets/credentials only — security tooling presence is Agent 7's concern.
Agent 1 — Injection & Input Validation: SQL injection, NoSQL injection, command injection, LDAP injection, XPath injection, template injection (SSTI), header injection, log injection. Check that all user input is validated at system boundaries, parameterized queries are used, and no string concatenation builds queries or commands.
If web_app = true, also check:
@ symbol (https://legit.com@evil.com), subdomain abuse (legit.com.evil.com), protocol-relative URLs (//evil.com), javascript: URIs, double URL encoding (%252f%252f), backslash normalization, null bytes, IDN homograph attacks (Cyrillic lookalikes), data: URIs, fragment abuse. Verify redirects use an allowlist or restrict to relative paths with proper validation.postMessage data from iframes, localStorage/sessionStorage values rendered to DOM, error messages reflecting user input, PDF/document generators accepting HTML, email templates with user data, admin log viewers, JSON responses rendered as HTML, SVG uploads (can contain JavaScript), and markdown rendering that allows raw HTML.% and _ wildcards), IN clauses with dynamic lists.If compliance_framework includes gdpr, also check:
If php_detected = true, also check:
==) with "0e..." strings, "0" == false, "" == 0 — flag security-sensitive comparisons using == instead of ===preg_replace with /e modifier (RCE), assert() with string argument (code evaluation), extract() on user input (variable overwrite), zip:// wrapper LFIparse_url() vs curl parsing discrepancy: double-@ in URLs parsed differently, enabling SSRF bypassEncoding/parsing mismatch checks (all languages):
if len(userInput) < maxLen or if len(token) == expected where len() enforces security boundaries on user-supplied strings — len() returns byte count, not character count. Correct check: utf8.RuneCountInString()Prototype pollution (JavaScript/TypeScript):
__proto__, constructor.prototype in user input reaching Object.assign, lodash.merge, or similar deep-merge functionsAgent 2 — Authentication, Authorization & Session Management: Broken auth flows, missing authorization checks on endpoints, IDOR, privilege escalation (horizontal and vertical), insecure session handling, JWT misuse (algorithm confusion, missing expiry, weak secrets), OAuth/OIDC misconfigurations, missing rate limiting on auth endpoints, account enumeration via error messages, insecure password storage, missing MFA considerations, session fixation, token leakage.
If web_app = true, also check:
alg: none acceptance and algorithm confusion (e.g., RS256 key used as HMAC secret).User.update(req.body), Model.objects.create(**request.data)). Require explicit field whitelisting.If compliance_framework includes pci-dss, also check:
If compliance_framework includes hipaa, also check:
If compliance_framework includes soc2, also check:
Additional auth/session attack patterns:
srand(time())) — flag any use of predictable seeds for session-related randomnessredirect_uri bypass variants: path traversal within allowed domain, fragment injection, subdomain matching tricksAgent 3 — Data Exposure & Cryptography: Insecure cryptographic choices (MD5/SHA1 for passwords, ECB mode, weak key sizes, static IVs/nonces), missing encryption at rest/in transit, PII exposure in API responses, verbose error messages leaking internals, source maps in production, insecure randomness (Math.random for security), missing data classification, overly broad API response serialization (returning full objects instead of DTOs).
If compliance_framework includes pci-dss, also check:
If compliance_framework includes hipaa, also check:
If compliance_framework includes gdpr, also check:
Agent 4 — Infrastructure & Supply Chain: SSRF vectors, path traversal, insecure file uploads, insecure deserialization, XXE, CORS misconfiguration, missing security headers (CSP, HSTS, X-Content-Type-Options, Referrer-Policy), open redirects, CSRF gaps, clickjacking, dependency vulnerabilities (check lock files for known-vulnerable versions), prototype pollution (JS), unsafe eval/exec, race conditions (TOCTOU), mass assignment, HTTP request smuggling vectors, insecure TLS configuration, missing rate limiting, DoS vectors (ReDoS, unbounded allocation).
If web_app = true, also check:
2130706433 = 127.0.0.1), octal IP (0177.0.0.1), hex IP (0x7f.0x0.0x0.0x1), IPv6 localhost ([::1]), IPv4-mapped IPv6 ([::ffff:127.0.0.1]), shortened notation (127.1), IPv6 scope IDs ([fe80::1%25eth0]), DNS rebinding, CNAME-to-internal, URL parser confusion (attacker.com#@internal), and redirect chains from external to internal. Verify cloud metadata endpoints are blocked: 169.254.169.254, metadata.google.internal. Check that DNS is resolved before requests and the resolved IP is pinned (no re-resolution).shell.php.jpg), null byte in filename (shell.php%00.jpg), MIME type spoofing (Content-Type doesn't match actual file), magic byte injection (valid header prepended to malicious file), polyglot files (valid as multiple types), SVG with embedded JavaScript, XXE via Office documents (DOCX/XLSX are ZIP+XML), ZIP slip (../../../etc/passwd in archive paths), filename injection (shell metacharacters in filename), ImageMagick exploits. Verify: file extension allowlist, magic byte validation (JPEG=FF D8 FF, PNG=89 50 4E 47, PDF=25 50 44 46), files renamed to random UUIDs, stored outside webroot, served with Content-Disposition: attachment and X-Content-Type-Options: nosniff.setFeature("disallow-doctype-decl", true), disable external general/parameter entities), Python (lxml with resolve_entities=False, no_network=True, or defusedxml), PHP (libxml_disable_entity_loader(true)), Node.js (DTD processing disabled), .NET (DtdProcessing = DtdProcessing.Prohibit, XmlResolver = null). Check indirect XML sources: Office documents, SVG files, SAML assertions, RSS/Atom feeds.Deserialization depth (all projects, not just web):
XMLDecoder on user-controlled inputxsi:type polymorphism enabling JNDI/RMI injectionpickle.loads() / cPickle.loads() called on user-controlled data — check input provenance regardless of HMAC signingIf iac_detected = true, also check:
Action: "*" with Resource: "*", AdministratorAccess, roles with iam:PassRole on *, missing conditions/scope restrictions.0.0.0.0/0 on non-80/443 ports, databases with public endpoints.tfvars or CF parameters with NoEcho: false.hostNetwork: true, automountServiceAccountToken not disabled, :latest image tags.When iac_detected = true, Agent 4's finding limit increases to max 15 to accommodate infrastructure findings alongside its existing scope.
Agent 5 — Secrets & Sensitive Data Leakage: This agent performs a dedicated secrets scan. It MUST:
5a. Scan source files for hardcoded secrets using these high-signal patterns:
(sk|pk|api|key|token|secret|password|passwd|credential|auth)[_-]?\w{16,}, AIza[0-9A-Za-z-_]{35} (Google), AKIA[0-9A-Z]{16} (AWS), sk-[a-zA-Z0-9]{20,} (OpenAI/Stripe), ghp_[a-zA-Z0-9]{36} (GitHub PAT), glpat-[a-zA-Z0-9-_]{20,} (GitLab PAT)(postgres|mysql|mongodb|redis|amqp|smtp)://[^\s'"]+@[^\s'"]+-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_.+/=]+secret, password, token, key, credential, api_key, apikey, auth, access_token, privatehooks.slack.com/services/T[A-Z0-9]+/B[A-Z0-9]+/[a-zA-Z0-9]+, Discord webhook URLs5b. Scan configuration and metadata files:
.env, .env.*, *.env files checked into the repo (should be in .gitignore)docker-compose*.yml, Dockerfile* for embedded secrets or ARG/ENV with secret values.github/workflows/*.yml, .gitlab-ci.yml, Jenkinsfile, .circleci/config.yml) for inline secrets (vs. proper secret references like ${{ secrets.X }})terraform.tfvars, *.auto.tfvars, terraform.tfstate for cloud credentialsapplication.yml, application.properties, appsettings.json, config.py, settings.py for hardcoded secretspackage.json, pyproject.toml, Cargo.toml for scripts that embed secrets*secret*.yml, *secret*.yaml) with non-reference values5c. Check .gitignore completeness:
Verify .gitignore exists and covers all categories below. Flag each missing category as a separate finding.
.claude/, .cursor/, .aider*, .continue/, .copilot/, .codeium/, .windsurf/, .tabnine/, .sourcegraph/ — these often contain conversation history, tool configs, plans, API keys, and cached credentials. Severity: high if missing (leaks workflow, prompts, and potentially embedded secrets)..idea/, .vscode/ (except shared settings like extensions.json), *.swp, *.swo, *~, .project, .classpath, .settings/ — may contain local paths, debug configs with credentials. Severity: low..env*, *.pem, *.key, *.p12, *.pfx, *.jks, *.keystore, *.crt (private certs), credentials.json, service-account*.json, *secret*, *.gpg (unless public keys). Severity: high if missing.terraform.tfstate, terraform.tfstate.backup, *.tfvars, .terraform/, pulumi.*.yaml (with secrets). Severity: high if missing (cloud credentials, resource IDs)..DS_Store, Thumbs.db, Desktop.ini, ._*. Severity: low.node_modules/, __pycache__/, *.pyc, .venv/, venv/, dist/, build/, *.egg-info/, target/, vendor/ (if not vendored intentionally). Severity: low..pre-commit-config.yaml with detect-secrets, gitleaks, trufflehog)? If neither exists, flag as medium: "No secrets scanning tooling configured. Recommend adding a .pre-commit-config.yaml with gitleaks to prevent secrets from being committed." Include a concrete fix with the minimal config snippet:
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.2
hooks:
- id: gitleaks
5d. Check for sensitive data in logs and error handling:
password, token, secret, key, credential, authorization, cookie, session5e. Check git history exposure (only if in a git repo):
git log --all --diff-filter=D -- '*.env' '*.pem' '*.key' '*.p12' '*.pfx' to check if secret files were committed then deleted (still in history)git log --all -p -S 'password' --max-count=5 -- '*.py' '*.js' '*.ts' '*.go' '*.java' '*.rb' to sample whether passwords were ever committed in sourcegit filter-repo) or credential rotationIf compliance_framework includes gdpr, also check:
Agent 6 — Web Application Security (only if web_app = true): This agent covers cross-cutting web concerns that span multiple categories. It reviews:
Security headers completeness: Verify all responses include the full recommended set with correct values:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadContent-Security-Policy: Verify default-src 'self', script-src does NOT include 'unsafe-inline' or 'unsafe-eval' (use nonces/hashes instead), frame-ancestors 'none' (or appropriate value), base-uri 'self', form-action 'self'. Flag overly permissive policies (wildcard * sources, data: in script-src).X-Content-Type-Options: nosniffX-Frame-Options: DENYReferrer-Policy: strict-origin-when-cross-origin (or stricter)Cache-Control: no-store on pages serving sensitive/authenticated contentPermissions-Policy restricting unnecessary browser featuresCSP bypass patterns: cloud platform domain whitelisting (.run.app, .cloudfunctions.net in script-src), <base> tag hijacking when base-uri directive is missing, <link rel="prefetch"> scriptless exfiltration. Flag behavioral framework attribute execution (hx-get, x-data, _) only when attribute values are populated from unsanitized user input — mere presence is NOT a finding.
CSS-only data exfiltration: via container queries + custom fonts (no JavaScript needed) — report as impact escalation on any identified CSS injection finding, not as a standalone finding
DOM clobbering: named form elements (name="location", id="cookie") overriding global variables — flag when user-controlled HTML is rendered without sanitization that strips name/id attributes
CORS configuration: Check Access-Control-Allow-Origin — flag * (wildcard) on authenticated endpoints, flag dynamic origin reflection without allowlist validation, check Access-Control-Allow-Credentials: true is only used with specific origins (never with *), verify Access-Control-Allow-Methods and Access-Control-Allow-Headers are restrictive.
Cookie security attributes: Audit all Set-Cookie calls for:
HttpOnly flag (prevents JS access — required for session/auth cookies)Secure flag (HTTPS-only — required for all sensitive cookies)SameSite=Strict or SameSite=Lax (flag SameSite=None without justification)Path and Domain scoping (avoid overly broad cookie scope)Max-Age/Expires — flag session cookies that never expire)Client-side secret exposure: Check for secrets in JavaScript bundles, source maps shipped to production, HTML comments, hidden form fields, data attributes, localStorage/sessionStorage writes of tokens/keys, initial state/hydration data in SSR apps (Next.js getServerSideProps, Nuxt asyncData, etc.), and environment variables exposed via build tools (NEXT_PUBLIC_*, REACT_APP_*, VITE_*).
Sensitive data in client responses: Check API responses for fields that should not reach the client: password hashes, internal IDs, full SSNs, unmasked credit card numbers, email addresses of other users, internal infrastructure details, debug information, or full stack traces. Verify DTOs/serializers restrict output fields.
Agent 7 — CI/CD Pipeline Security: Scan CI configs (.github/workflows/*.yml, .gitlab-ci.yml, Jenkinsfile, .circleci/config.yml, azure-pipelines.yml) for security tooling presence. This agent always runs (not conditional).
github/codeql-action, semgrep steps, or equivalent..github/dependabot.yml), Renovate (renovate.json), npm audit, pip-audit.web_app = true.- uses: semgrep/semgrep-action@v1
- uses: aquasecurity/trivy-action@master
with: { scan-type: 'fs' }
If compliance_framework includes soc2, also check:
Each subagent's prompt MUST be assembled verbatim from the shared fragments in ~/.claude/rules/review-output-contract.md plus this skill's domain-specific content. Read that file (when working inside the claude_extensions repo itself it is also at rules/review-output-contract.md) and inline the named fragment in place of each <<shared:…>> marker below; inline every other line exactly as written:
Approach the code from an attacker's perspective. For each issue found, verify it is actually exploitable in context — do not flag theoretical issues that are mitigated elsewhere. Check if a framework or middleware already handles the concern before reporting.
- Severity: critical | high | medium | low
- Category: OWASP category or CWE ID (e.g., "A03:2021 Injection", "CWE-798 Hardcoded Credentials")
- Location: file path and line number or function name
- Issue: one-sentence description of the vulnerability
- Impact: one-sentence description of what an attacker could achieve — quantify blast radius from code context where possible (e.g., "exposes entire users table" not just "exposes user data"; "affects every authenticated API endpoint" not just "auth bypass possible")
- Fix: one-sentence concrete remediation (not "consider" or "review" — state what to do)
- Evidence: the specific code snippet (max 3 lines) that demonstrates the issue
Severity guide:
critical: Directly exploitable, leads to RCE, full data breach, or auth bypass. No additional access needed.
high: Exploitable with some preconditions, leads to significant data exposure, privilege escalation, or account takeover.
medium: Exploitable but limited impact, or requires significant preconditions. Includes missing security hardening that enables other attacks.
low: Defense-in-depth gap, informational, or best-practice violation with minimal direct exploitability.
Rationalizations to Reject — Do not accept these dismissals as justification for downgrading or omitting findings:
- "It's behind a VPN / internal only" — internal networks get breached; defense in depth applies
- "Only admins can reach this endpoint" — admin accounts get compromised; least privilege still matters
- "We sanitize input elsewhere" — verify the sanitization exists and covers this path; don't assume
- "It's just a dev/staging environment" — dev environments often mirror prod data and credentials
- "The framework handles that automatically" — verify the framework config; defaults aren't always secure
- "We'll fix it before launch" — security debt compounds; fix now or track with a deadline
- "No attacker would find this" — security through obscurity is not a control
- "It only runs in CI" — CI environments have secrets, network access, and deploy permissions
- "The algorithm is widely used / industry standard" — widespread adoption ≠ secure in context; watch for dismissals like "we use bcrypt — except this one legacy endpoint" that concede the exception while waving it off
Red Flags — STOP and Re-examine — If you catch yourself thinking any of these, stop and reconsider:
- "This looks like standard auth code, probably fine" — STOP. Auth code is where the most critical bugs live.
- "I don't see any obvious injection points" — STOP. The non-obvious ones are the ones that ship to production.
- "The input is coming from another internal service" — STOP. Internal services get compromised. Validate at every trust boundary.
- "This crypto code matches common patterns" — STOP. Common patterns are commonly misused. Verify parameters, modes, and key sizes.
- "I've already checked this type of issue in another file" — STOP. Each file has its own context. Check again.
After all subagents complete, the main session:
web_app = true, note which web-specific checks were performed. If iac_detected = true, note which IaC tools were reviewed. If php_detected = true, note that PHP-specific checks were enabled.compliance_framework is set): list which framework controls were checked and any gaps. Add disclaimer: "This review checks for common technical controls associated with [framework]. It is not a substitute for formal compliance assessment by a qualified auditor."If the user wants to fix issues:
validate_user in auth.py") — do not use line numbers for BEFORE evidence, as they shift after edits. Note: the findings Location field format (which may include line numbers) is unchanged.After applying fixes, automatically verify them:
model override so they inherit the session model; fix verification is high-stakes — don't downgrade to a cheaper tier; CLAUDE_CODE_SUBAGENT_MODEL overrides if set):
iac_detected = true, plus checking that fixes didn't introduce new issues or new secret leaks)~/.claude/rules/review-output-contract.md as described there), modified to say: "Review ONLY the following changed files/sections: [list]. Read at most 3 additional context files. Max 5 items. Also verify that the applied fixes are correct and complete — check for regressions."When the stop condition is met, present a final summary:
If the user does not approve fixes at any point, present the findings as a reference and end. Do not modify any files.
The final synthesized report MUST include all of the following:
compliance_framework argument was providedpass (0 critical, 0 high), conditional-pass (0 critical, 1+ high), or fail (1+ critical)