Security Audit
Perform a structured security assessment of an application. This skill goes far deeper than the security checklist in code-reviewing — it's a dedicated, systematic analysis covering the OWASP Top 10 and beyond.
Scope Boundary
This skill analyzes code, configuration, and architecture for security vulnerabilities through static analysis and design review. It does not replace penetration testing, but it prepares code for one by catching the issues a pentester would find. It is the reactive half of the pair: for design-time analysis of a system that isn't built yet (trust boundaries, STRIDE, abuse cases), use threat-modeling — and when a threat model exists, use it as this audit's checklist.
⛔ The Iron Law
"No obvious problems" is not a pass.
Absence of evidence is not evidence of security. Every clearance is backed by evidence — the specific control you read and where it's enforced — and every finding cites the exact code path plus a concrete exploit scenario. If you can't write the exploit, you haven't assessed the risk; if you can, it isn't theoretical.
Workflow
Step 1: Define the Attack Surface
Before reviewing code line by line, map what's exposed:
- Entry points: HTTP endpoints, WebSocket connections, GraphQL resolvers, CLI inputs, file uploads, webhooks, cron jobs
- Authentication boundaries: What's public vs authenticated vs admin-only?
- Data flows: Where does sensitive data enter, travel, and get stored?
- External integrations: Third-party APIs, OAuth providers, payment processors
- Infrastructure: Cloud services, databases, caches, queues
Record the attack surface map as the first section of the report — gaps in understanding here mean gaps in the audit, so anything you could not map (unreachable config, undocumented integrations) goes under Open questions rather than being assumed safe.
Step 2: Assess by OWASP Top 10
Walk through each category systematically. See references/owasp-top-10.md for the detailed checklist.
For each finding:
- Severity: Critical / High / Medium / Low
- Location: File, line, endpoint
- Vulnerability: What the issue is
- Exploit scenario: How an attacker would use this (concrete, not theoretical)
- Remediation: Specific code change or configuration fix
Step 3: Authentication & Authorization Deep Dive
Auth is where the highest-impact vulnerabilities live. Review:
Authentication:
- How are credentials stored? (bcrypt/argon2 with sufficient rounds, never MD5/SHA)
- Session management: secure flags, httpOnly, sameSite, expiration
- Token handling: JWT validation (algorithm, expiry, issuer), refresh token rotation
- Password policy: minimum complexity, breached password checking
- MFA implementation (if present): bypass resistance, recovery flow security
- Rate limiting on login: brute force protection
Authorization:
- Is authorization checked on every protected endpoint (not just the UI)?
- Are there IDOR vulnerabilities? (Can user A access user B's resources by changing an ID?)
- Is the authorization model consistent? (role-based, attribute-based, or ad-hoc?)
- Are there privilege escalation paths? (Can a regular user reach admin functionality?)
- Are API endpoints and UI permissions in sync?
Step 4: Data Security Review
- At rest: Is sensitive data encrypted in the database? (PII, payment data, health data)
- In transit: Is TLS enforced everywhere? Any HTTP-only endpoints?
- In logs: Are passwords, tokens, SSNs, or credit card numbers logged?
- In errors: Do error messages leak internal details (stack traces, SQL queries, file paths)?
- In responses: Do API responses include fields the client shouldn't see?
- Retention: Is data deleted when it should be? GDPR/CCPA compliance?
Step 5: Dependency Audit
Run dependency vulnerability scanners and review results:
# JavaScript/TypeScript
npm audit
npx better-npm-audit audit
# Python
pip audit
safety check
# Go
govulncheck ./...
# Ruby
bundle audit check --update
For each vulnerability found:
- What is the CVE and its severity?
- Is the vulnerable code path actually used in this project?
- Is there a patched version available?
- If no patch exists, what's the mitigation?
Suggest using the dependency-management skill for remediation planning.
Step 6: Secrets and Configuration
- Scan for hardcoded secrets: API keys, passwords, tokens, private keys
- Check
.gitignore covers sensitive files (.env, key files, certificates)
- Review git history for accidentally committed secrets:
git log --all -p | grep -i "password\|secret\|api_key\|token"
- Verify environment variable usage for all secrets
- Check that different environments use different credentials
Step 7: Produce the Report
Output the audit report using the template at templates/security-report.md. Organize findings by severity, with Critical and High items first.
Write the full report to a file (default a gitignored location, e.g.
.local/security-audit-<date>.md) and state its path in your final summary — this
skill runs in a forked context: only the summary returns, everything unwritten is
lost. The summary must lead with the Critical/High count. Judgment calls that need
user input (unclear trust boundary, whether a data store is in scope, unverifiable
control) go in an Open questions section of the report — never silently assumed
safe.
What This Skill Does NOT Cover
- Runtime penetration testing (requires running the application)
- Network-level security (firewall rules, VPN configuration)
- Physical security or social engineering
- Compliance certification (SOC 2, HIPAA, PCI DSS — though findings may relate)
Principles Applied
- Defense in depth: Don't rely on a single security control. Layer protections.
- Least privilege: Every component should have the minimum permissions it needs.
- Fail secure: When something goes wrong, it should deny access, not grant it.
- KISS: Simpler security is more auditable security. Complex auth flows breed bugs.
Rationalizations to reject
| Excuse |
Reality |
| "I didn't see anything obviously wrong" |
You audited the absence of obvious bugs, not the presence of security. Trace each control. |
| "The framework handles that" |
Verify the control is actually enabled and configured correctly — don't assume. |
| "Auth is checked in the UI" |
UI checks are not authorization. Confirm server-side enforcement on every protected endpoint. |
| "This input is internal/trusted" |
Trust boundaries shift. Validate anyway — defense in depth. |
| "That CVE doesn't apply to us" |
Confirm the vulnerable code path is unused before dismissing it. |
| "It's only a theoretical risk" |
If you can't write the exploit scenario, you haven't assessed it. |
Red flags — stop and correct course
- Signing off a category without naming the file/endpoint you verified.
- A finding with no concrete exploit path.
- Concluding "secure" because nothing jumped out.
- Trusting that a control exists without reading where it's enforced.
1---2name: security-audit3description: Comprehensive security analysis — OWASP Top 10, auth/authz flows, injection vulnerabilities, data exposure, secrets detection, dependency CVEs, hardening recommendations. Reviews EXISTING code/config — design-time analysis of a system not yet built → threat-modeling.4---56# Security Audit78Perform a structured security assessment of an application. This skill goes far deeper than the security checklist in code-reviewing — it's a dedicated, systematic analysis covering the OWASP Top 10 and beyond.910## Scope Boundary1112This skill analyzes code, configuration, and architecture for security vulnerabilities through static analysis and design review. It does not replace penetration testing, but it prepares code for one by catching the issues a pentester would find. It is the *reactive* half of the pair: for design-time analysis of a system that isn't built yet (trust boundaries, STRIDE, abuse cases), use `threat-modeling` — and when a threat model exists, use it as this audit's checklist.1314## ⛔ The Iron Law1516**"No obvious problems" is not a pass.**1718Absence of evidence is not evidence of security. Every clearance is backed by evidence — the specific control you read and where it's enforced — and every finding cites the exact code path plus a concrete exploit scenario. If you can't write the exploit, you haven't assessed the risk; if you can, it isn't theoretical.1920## Workflow2122### Step 1: Define the Attack Surface2324Before reviewing code line by line, map what's exposed:2526- **Entry points**: HTTP endpoints, WebSocket connections, GraphQL resolvers, CLI inputs, file uploads, webhooks, cron jobs27- **Authentication boundaries**: What's public vs authenticated vs admin-only?28- **Data flows**: Where does sensitive data enter, travel, and get stored?29- **External integrations**: Third-party APIs, OAuth providers, payment processors30- **Infrastructure**: Cloud services, databases, caches, queues3132Record the attack surface map as the first section of the report — gaps in understanding here mean gaps in the audit, so anything you could not map (unreachable config, undocumented integrations) goes under Open questions rather than being assumed safe.3334### Step 2: Assess by OWASP Top 103536Walk through each category systematically. See [references/owasp-top-10.md](references/owasp-top-10.md) for the detailed checklist.3738For each finding:3940- **Severity**: Critical / High / Medium / Low41- **Location**: File, line, endpoint42- **Vulnerability**: What the issue is43- **Exploit scenario**: How an attacker would use this (concrete, not theoretical)44- **Remediation**: Specific code change or configuration fix4546### Step 3: Authentication & Authorization Deep Dive4748Auth is where the highest-impact vulnerabilities live. Review:4950**Authentication:**51- How are credentials stored? (bcrypt/argon2 with sufficient rounds, never MD5/SHA)52- Session management: secure flags, httpOnly, sameSite, expiration53- Token handling: JWT validation (algorithm, expiry, issuer), refresh token rotation54- Password policy: minimum complexity, breached password checking55- MFA implementation (if present): bypass resistance, recovery flow security56- Rate limiting on login: brute force protection5758**Authorization:**59- Is authorization checked on every protected endpoint (not just the UI)?60- Are there IDOR vulnerabilities? (Can user A access user B's resources by changing an ID?)61- Is the authorization model consistent? (role-based, attribute-based, or ad-hoc?)62- Are there privilege escalation paths? (Can a regular user reach admin functionality?)63- Are API endpoints and UI permissions in sync?6465### Step 4: Data Security Review6667- **At rest**: Is sensitive data encrypted in the database? (PII, payment data, health data)68- **In transit**: Is TLS enforced everywhere? Any HTTP-only endpoints?69- **In logs**: Are passwords, tokens, SSNs, or credit card numbers logged?70- **In errors**: Do error messages leak internal details (stack traces, SQL queries, file paths)?71- **In responses**: Do API responses include fields the client shouldn't see?72- **Retention**: Is data deleted when it should be? GDPR/CCPA compliance?7374### Step 5: Dependency Audit7576Run dependency vulnerability scanners and review results:7778```bash79# JavaScript/TypeScript80npm audit81npx better-npm-audit audit8283# Python84pip audit85safety check8687# Go88govulncheck ./...8990# Ruby91bundle audit check --update92```9394For each vulnerability found:95- What is the CVE and its severity?96- Is the vulnerable code path actually used in this project?97- Is there a patched version available?98- If no patch exists, what's the mitigation?99100Suggest using the `dependency-management` skill for remediation planning.101102### Step 6: Secrets and Configuration103104- Scan for hardcoded secrets: API keys, passwords, tokens, private keys105- Check `.gitignore` covers sensitive files (`.env`, key files, certificates)106- Review git history for accidentally committed secrets: `git log --all -p | grep -i "password\|secret\|api_key\|token"`107- Verify environment variable usage for all secrets108- Check that different environments use different credentials109110### Step 7: Produce the Report111112Output the audit report using the template at [templates/security-report.md](templates/security-report.md). Organize findings by severity, with Critical and High items first.113114**Write the full report to a file** (default a gitignored location, e.g.115`.local/security-audit-<date>.md`) and state its path in your final summary — this116skill runs in a forked context: only the summary returns, everything unwritten is117lost. The summary must lead with the Critical/High count. Judgment calls that need118user input (unclear trust boundary, whether a data store is in scope, unverifiable119control) go in an **Open questions** section of the report — never silently assumed120safe.121122## What This Skill Does NOT Cover123124- Runtime penetration testing (requires running the application)125- Network-level security (firewall rules, VPN configuration)126- Physical security or social engineering127- Compliance certification (SOC 2, HIPAA, PCI DSS — though findings may relate)128129## Principles Applied130131- **Defense in depth**: Don't rely on a single security control. Layer protections.132- **Least privilege**: Every component should have the minimum permissions it needs.133- **Fail secure**: When something goes wrong, it should deny access, not grant it.134- **KISS**: Simpler security is more auditable security. Complex auth flows breed bugs.135136## Rationalizations to reject137138| Excuse | Reality |139|--------|---------|140| "I didn't see anything obviously wrong" | You audited the absence of obvious bugs, not the presence of security. Trace each control. |141| "The framework handles that" | Verify the control is actually enabled and configured correctly — don't assume. |142| "Auth is checked in the UI" | UI checks are not authorization. Confirm server-side enforcement on every protected endpoint. |143| "This input is internal/trusted" | Trust boundaries shift. Validate anyway — defense in depth. |144| "That CVE doesn't apply to us" | Confirm the vulnerable code path is unused before dismissing it. |145| "It's only a theoretical risk" | If you can't write the exploit scenario, you haven't assessed it. |146147## Red flags — stop and correct course148149- Signing off a category without naming the file/endpoint you verified.150- A finding with no concrete exploit path.151- Concluding "secure" because nothing jumped out.152- Trusting that a control exists without reading where it's enforced.