Security Review
Overview
Systematically review code for security vulnerabilities, apply secure coding patterns, and ensure applications follow defense-in-depth principles. This skill covers the OWASP Top 10, authentication pattern selection, input validation, secrets management, dependency auditing, security headers, and threat modeling.
Announce at start: "I'm using the security-review skill to assess security posture."
Phase 1: Scope and Threat Assessment
Goal: Identify the attack surface and prioritize review areas.
Actions
- Identify all user-facing endpoints and input surfaces
- Map authentication and authorization boundaries
- List external dependencies and their trust levels
- Identify sensitive data flows (PII, credentials, payment)
- Determine compliance requirements (SOC 2, GDPR, HIPAA)
STOP — Do NOT proceed to Phase 2 until:
Phase 2: OWASP Top 10 Audit
Goal: Systematically check against each OWASP category.
OWASP Top 10 Checklist (2021)
| # |
Category |
Key Check |
Pass/Fail |
| 1 |
Broken Access Control |
Authorization verified on every endpoint, deny by default |
|
| 2 |
Cryptographic Failures |
No plaintext secrets, strong algorithms (AES-256, bcrypt) |
|
| 3 |
Injection |
Parameterized queries, no string concatenation for SQL/commands |
|
| 4 |
Insecure Design |
Threat model exists, rate limiting, abuse cases considered |
|
| 5 |
Security Misconfiguration |
No defaults in production, minimal permissions, error messages leak nothing |
|
| 6 |
Vulnerable Components |
Dependencies audited, no known CVEs, update policy in place |
|
| 7 |
Auth Failures |
MFA available, passwords hashed, session management secure |
|
| 8 |
Data Integrity Failures |
Verify signatures, validate CI/CD pipeline integrity |
|
| 9 |
Logging Failures |
Log auth events, access control failures, input validation failures |
|
| 10 |
SSRF |
Validate/allowlist URLs, no internal network access from user input |
|
STOP — Do NOT proceed to Phase 3 until:
Phase 3: Deep Review by Category
Goal: Apply detailed security patterns to identified issues.
Auth Pattern Selection Table
| Pattern |
Use When |
Key Requirements |
| JWT |
Stateless APIs, microservices, mobile backends |
RS256 for multi-service; access token 15min max; HttpOnly cookies |
| Session-based |
Traditional web apps, server-rendered pages |
Server-side storage; HttpOnly + Secure + SameSite cookies; CSRF tokens |
| OAuth2/OIDC |
Third-party login, SSO, delegated auth |
Authorization Code + PKCE; validate ID token claims; server-side token storage |
| Passkeys/WebAuthn |
Passwordless, high-security apps |
Phishing-resistant; store public keys only; support multiple per account |
JWT Security Checklist
| Aspect |
Guidance |
| Signing |
RS256 (asymmetric) for multi-service, HS256 for single service |
| Expiry |
Access token: 15 minutes max. Refresh token: 7 days max |
| Storage |
HttpOnly cookie (web) or secure storage (mobile). Never localStorage |
| Refresh |
Rotate refresh tokens on use, invalidate on logout |
| Payload |
Minimal claims (sub, exp, iat, roles). No sensitive data |
Input Validation Patterns
Allow-List Validation (always prefer over block-list):
# Good: allow-list
ALLOWED_SORT_FIELDS = {'name', 'created_at', 'price'}
if sort_field not in ALLOWED_SORT_FIELDS:
raise ValidationError("Invalid sort field")
# Bad: block-list (always incomplete)
BLOCKED_CHARS = ['<', '>', '"']
Parameterized Queries (never concatenate user input):
# Good: parameterized
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
# Bad: SQL injection vulnerability
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
File Upload Validation
- Validate MIME type server-side (not just extension)
- Enforce file size limits
- Generate random filenames (never use user-supplied names)
- Store uploads outside the web root
- Scan for malware if accepting from untrusted users
STOP — Do NOT proceed to Phase 4 until:
Phase 4: Infrastructure and Dependency Hardening
Goal: Secure the deployment environment and supply chain.
Secrets Management Rules
| Environment |
Method |
| Development |
.env files (git-ignored) |
| CI/CD |
Pipeline secrets (GitHub Secrets, GitLab CI vars) |
| Production |
Secrets manager (AWS Secrets Manager, Vault, GCP Secret Manager) |
Secrets Never List
- Never hard-code secrets in source code
- Never commit
.env files to git
- Never log secrets (even at debug level)
- Never pass secrets as command-line arguments
- Never use the same secrets across environments
Dependency Auditing Commands
# Node.js
npm audit
npx socket-security audit
# Python
pip-audit
safety check
# Go
govulncheck ./...
# Rust
cargo audit
Security Headers
| Header |
Value |
Purpose |
Content-Security-Policy |
default-src 'self' (customize per app) |
Prevents XSS, data injection |
Strict-Transport-Security |
max-age=63072000; includeSubDomains |
Forces HTTPS |
X-Content-Type-Options |
nosniff |
Prevents MIME sniffing |
X-Frame-Options |
DENY or SAMEORIGIN |
Prevents clickjacking |
Referrer-Policy |
strict-origin-when-cross-origin |
Controls referer leakage |
Permissions-Policy |
Disable unused APIs |
Limits browser feature access |
CORS Rules
- Never use
Access-Control-Allow-Origin: * with credentials
- Allowlist specific origins
- Restrict allowed methods and headers to what is needed
Phase 5: Threat Modeling (STRIDE)
Goal: For new features or significant changes, walk through each threat category.
| Threat |
Question |
Mitigation |
| Spoofing |
Can an attacker pretend to be someone else? |
Strong authentication, MFA |
| Tampering |
Can data be modified without detection? |
Integrity checks, signatures |
| Repudiation |
Can a user deny performing an action? |
Audit logging |
| Information Disclosure |
Can sensitive data leak through errors, logs, or side channels? |
Error sanitization, encryption |
| Denial of Service |
Can the system be overwhelmed? |
Rate limits, resource quotas |
| Elevation of Privilege |
Can a user gain permissions they should not have? |
Least privilege, RBAC |
For each identified threat:
- Document the threat and attack vector
- Assess likelihood and impact
- Define mitigations
- Verify mitigations are implemented and tested
Decision Table: Security Review Depth
| Change Type |
Review Depth |
Focus Areas |
| Auth/session changes |
Full STRIDE + OWASP |
All categories |
| User input handling |
Injection + validation focus |
OWASP 1, 3, 10 |
| Dependency update |
CVE scan + changelog review |
OWASP 6 |
| API endpoint addition |
Access control + input validation |
OWASP 1, 3, 5 |
| Config/infrastructure |
Secrets + headers + misconfig |
OWASP 2, 5 |
| File upload feature |
Injection + SSRF + malware |
OWASP 3, 10 |
Anti-Patterns / Common Mistakes
| Anti-Pattern |
Why It Is Wrong |
Correct Approach |
| Client-side only validation |
Easily bypassed |
Always validate server-side |
| Storing tokens in localStorage |
XSS can steal them |
Use HttpOnly cookies |
| Block-list input validation |
Always incomplete |
Use allow-list validation |
| Generic error messages in production |
May leak internal details |
Sanitize errors, log details server-side |
| Same secrets across environments |
Breach of one compromises all |
Unique secrets per environment |
| Ignoring dependency CVEs |
Known vulnerabilities are actively exploited |
Audit and update regularly |
| CORS wildcard with credentials |
Defeats CORS protection entirely |
Allowlist specific origins |
| Logging sensitive data |
Log exposure creates data breach |
Never log secrets, PII, or tokens |
Secrets Rotation Schedule
| Secret Type |
Rotation Frequency |
After Suspected Compromise |
| API keys |
Every 90 days |
Immediately |
| Database passwords |
Every 90 days |
Immediately |
| Encryption keys |
Annually (support key versioning) |
Immediately |
| JWT signing keys |
Every 6 months |
Immediately |
| OAuth client secrets |
Every 90 days |
Immediately |
Subagent Dispatch Opportunities
| Task Pattern |
Dispatch To |
When |
| Scanning different OWASP categories in parallel |
Agent tool with subagent_type="Explore" (one per category) |
When reviewing a large codebase across multiple vulnerability types |
| Authentication flow analysis |
Agent tool with subagent_type="general-purpose" |
When auth implementation spans multiple files/services |
| Dependency vulnerability scanning |
Bash tool with run_in_background=true |
When running npm audit or similar tools concurrently |
Follow the dispatching-parallel-agents skill protocol when dispatching.
Integration Points
| Skill |
Relationship |
code-review |
Security findings are Critical category issues |
senior-backend |
Backend hardening follows security review findings |
senior-fullstack |
Auth implementation follows security patterns |
acceptance-testing |
Security requirements become acceptance criteria |
performance-optimization |
Rate limiting serves both security and performance |
systematic-debugging |
Security incidents trigger debugging workflow |
Skill Type
FLEXIBLE — Adapt the depth of review to the change type using the decision table. The OWASP checklist and STRIDE analysis are strongly recommended for any auth or input-handling changes. Secrets management rules are non-negotiable.
1---2name: security-review3description: Use when reviewing code for security vulnerabilities, implementing authentication or authorization, handling user input, managing secrets, or auditing dependencies for known CVEs. Triggers: auth implementation, input handling, secrets management, dependency audit, pre-deployment security check, OWASP compliance review.4---5
6# Security Review
7
8## Overview
9
10Systematically review code for security vulnerabilities, apply secure coding patterns, and ensure applications follow defense-in-depth principles. This skill covers the OWASP Top 10, authentication pattern selection, input validation, secrets management, dependency auditing, security headers, and threat modeling.
11
12**Announce at start:** "I'm using the security-review skill to assess security posture."
13
14---
15
16## Phase 1: Scope and Threat Assessment
17
18**Goal:** Identify the attack surface and prioritize review areas.
19
20### Actions
21
221. Identify all user-facing endpoints and input surfaces
232. Map authentication and authorization boundaries
243. List external dependencies and their trust levels
254. Identify sensitive data flows (PII, credentials, payment)
265. Determine compliance requirements (SOC 2, GDPR, HIPAA)
27
28### STOP — Do NOT proceed to Phase 2 until:
29- [ ] Attack surface is mapped
30- [ ] Sensitive data flows are identified
31- [ ] Compliance requirements are known
32
33---
34
35## Phase 2: OWASP Top 10 Audit
36
37**Goal:** Systematically check against each OWASP category.
38
39### OWASP Top 10 Checklist (2021)
40
41| # | Category | Key Check | Pass/Fail |
42|---|----------|-----------|-----------|
43| 1 | **Broken Access Control** | Authorization verified on every endpoint, deny by default | |
44| 2 | **Cryptographic Failures** | No plaintext secrets, strong algorithms (AES-256, bcrypt) | |
45| 3 | **Injection** | Parameterized queries, no string concatenation for SQL/commands | |
46| 4 | **Insecure Design** | Threat model exists, rate limiting, abuse cases considered | |
47| 5 | **Security Misconfiguration** | No defaults in production, minimal permissions, error messages leak nothing | |
48| 6 | **Vulnerable Components** | Dependencies audited, no known CVEs, update policy in place | |
49| 7 | **Auth Failures** | MFA available, passwords hashed, session management secure | |
50| 8 | **Data Integrity Failures** | Verify signatures, validate CI/CD pipeline integrity | |
51| 9 | **Logging Failures** | Log auth events, access control failures, input validation failures | |
52| 10 | **SSRF** | Validate/allowlist URLs, no internal network access from user input | |
53
54### STOP — Do NOT proceed to Phase 3 until:
55- [ ] All 10 categories are checked
56- [ ] Findings are documented with severity
57
58---
59
60## Phase 3: Deep Review by Category
61
62**Goal:** Apply detailed security patterns to identified issues.
63
64### Auth Pattern Selection Table
65
66| Pattern | Use When | Key Requirements |
67|---------|----------|-----------------|
68| **JWT** | Stateless APIs, microservices, mobile backends | RS256 for multi-service; access token 15min max; HttpOnly cookies |
69| **Session-based** | Traditional web apps, server-rendered pages | Server-side storage; HttpOnly + Secure + SameSite cookies; CSRF tokens |
70| **OAuth2/OIDC** | Third-party login, SSO, delegated auth | Authorization Code + PKCE; validate ID token claims; server-side token storage |
71| **Passkeys/WebAuthn** | Passwordless, high-security apps | Phishing-resistant; store public keys only; support multiple per account |
72
73### JWT Security Checklist
74
75| Aspect | Guidance |
76|--------|----------|
77| Signing | RS256 (asymmetric) for multi-service, HS256 for single service |
78| Expiry | Access token: 15 minutes max. Refresh token: 7 days max |
79| Storage | HttpOnly cookie (web) or secure storage (mobile). Never localStorage |
80| Refresh | Rotate refresh tokens on use, invalidate on logout |
81| Payload | Minimal claims (sub, exp, iat, roles). No sensitive data |
82
83### Input Validation Patterns
84
85**Allow-List Validation** (always prefer over block-list):
86```python
87# Good: allow-list
88ALLOWED_SORT_FIELDS = {'name', 'created_at', 'price'}
89if sort_field not in ALLOWED_SORT_FIELDS:
90 raise ValidationError("Invalid sort field")
91
92# Bad: block-list (always incomplete)
93BLOCKED_CHARS = ['<', '>', '"']
94```
95
96**Parameterized Queries** (never concatenate user input):
97```python
98# Good: parameterized
99cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
100
101# Bad: SQL injection vulnerability
102cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
103```
104
105### File Upload Validation
106
107- Validate MIME type server-side (not just extension)
108- Enforce file size limits
109- Generate random filenames (never use user-supplied names)
110- Store uploads outside the web root
111- Scan for malware if accepting from untrusted users
112
113### STOP — Do NOT proceed to Phase 4 until:
114- [ ] All identified issues have remediation recommendations
115- [ ] Auth patterns are correctly applied
116- [ ] Input validation is comprehensive
117
118---
119
120## Phase 4: Infrastructure and Dependency Hardening
121
122**Goal:** Secure the deployment environment and supply chain.
123
124### Secrets Management Rules
125
126| Environment | Method |
127|-------------|--------|
128| Development | `.env` files (git-ignored) |
129| CI/CD | Pipeline secrets (GitHub Secrets, GitLab CI vars) |
130| Production | Secrets manager (AWS Secrets Manager, Vault, GCP Secret Manager) |
131
132### Secrets Never List
133
134- Never hard-code secrets in source code
135- Never commit `.env` files to git
136- Never log secrets (even at debug level)
137- Never pass secrets as command-line arguments
138- Never use the same secrets across environments
139
140### Dependency Auditing Commands
141
142```bash
143# Node.js
144npm audit
145npx socket-security audit
146
147# Python
148pip-audit
149safety check
150
151# Go
152govulncheck ./...
153
154# Rust
155cargo audit
156```
157
158### Security Headers
159
160| Header | Value | Purpose |
161|--------|-------|---------|
162| `Content-Security-Policy` | `default-src 'self'` (customize per app) | Prevents XSS, data injection |
163| `Strict-Transport-Security` | `max-age=63072000; includeSubDomains` | Forces HTTPS |
164| `X-Content-Type-Options` | `nosniff` | Prevents MIME sniffing |
165| `X-Frame-Options` | `DENY` or `SAMEORIGIN` | Prevents clickjacking |
166| `Referrer-Policy` | `strict-origin-when-cross-origin` | Controls referer leakage |
167| `Permissions-Policy` | Disable unused APIs | Limits browser feature access |
168
169### CORS Rules
170
171- Never use `Access-Control-Allow-Origin: *` with credentials
172- Allowlist specific origins
173- Restrict allowed methods and headers to what is needed
174
175---
176
177## Phase 5: Threat Modeling (STRIDE)
178
179**Goal:** For new features or significant changes, walk through each threat category.
180
181| Threat | Question | Mitigation |
182|--------|----------|-----------|
183| **Spoofing** | Can an attacker pretend to be someone else? | Strong authentication, MFA |
184| **Tampering** | Can data be modified without detection? | Integrity checks, signatures |
185| **Repudiation** | Can a user deny performing an action? | Audit logging |
186| **Information Disclosure** | Can sensitive data leak through errors, logs, or side channels? | Error sanitization, encryption |
187| **Denial of Service** | Can the system be overwhelmed? | Rate limits, resource quotas |
188| **Elevation of Privilege** | Can a user gain permissions they should not have? | Least privilege, RBAC |
189
190For each identified threat:
1911. Document the threat and attack vector
1922. Assess likelihood and impact
1933. Define mitigations
1944. Verify mitigations are implemented and tested
195
196---
197
198## Decision Table: Security Review Depth
199
200| Change Type | Review Depth | Focus Areas |
201|-------------|-------------|-------------|
202| Auth/session changes | Full STRIDE + OWASP | All categories |
203| User input handling | Injection + validation focus | OWASP 1, 3, 10 |
204| Dependency update | CVE scan + changelog review | OWASP 6 |
205| API endpoint addition | Access control + input validation | OWASP 1, 3, 5 |
206| Config/infrastructure | Secrets + headers + misconfig | OWASP 2, 5 |
207| File upload feature | Injection + SSRF + malware | OWASP 3, 10 |
208
209---
210
211## Anti-Patterns / Common Mistakes
212
213| Anti-Pattern | Why It Is Wrong | Correct Approach |
214|-------------|----------------|-----------------|
215| Client-side only validation | Easily bypassed | Always validate server-side |
216| Storing tokens in localStorage | XSS can steal them | Use HttpOnly cookies |
217| Block-list input validation | Always incomplete | Use allow-list validation |
218| Generic error messages in production | May leak internal details | Sanitize errors, log details server-side |
219| Same secrets across environments | Breach of one compromises all | Unique secrets per environment |
220| Ignoring dependency CVEs | Known vulnerabilities are actively exploited | Audit and update regularly |
221| CORS wildcard with credentials | Defeats CORS protection entirely | Allowlist specific origins |
222| Logging sensitive data | Log exposure creates data breach | Never log secrets, PII, or tokens |
223
224---
225
226## Secrets Rotation Schedule
227
228| Secret Type | Rotation Frequency | After Suspected Compromise |
229|------------|-------------------|--------------------------|
230| API keys | Every 90 days | Immediately |
231| Database passwords | Every 90 days | Immediately |
232| Encryption keys | Annually (support key versioning) | Immediately |
233| JWT signing keys | Every 6 months | Immediately |
234| OAuth client secrets | Every 90 days | Immediately |
235
236---
237
238## Subagent Dispatch Opportunities
239
240| Task Pattern | Dispatch To | When |
241|---|---|---|
242| Scanning different OWASP categories in parallel | `Agent` tool with `subagent_type="Explore"` (one per category) | When reviewing a large codebase across multiple vulnerability types |
243| Authentication flow analysis | `Agent` tool with `subagent_type="general-purpose"` | When auth implementation spans multiple files/services |
244| Dependency vulnerability scanning | `Bash` tool with `run_in_background=true` | When running `npm audit` or similar tools concurrently |
245
246Follow the `dispatching-parallel-agents` skill protocol when dispatching.
247
248---
249
250## Integration Points
251
252| Skill | Relationship |
253|-------|-------------|
254| `code-review` | Security findings are Critical category issues |
255| `senior-backend` | Backend hardening follows security review findings |
256| `senior-fullstack` | Auth implementation follows security patterns |
257| `acceptance-testing` | Security requirements become acceptance criteria |
258| `performance-optimization` | Rate limiting serves both security and performance |
259| `systematic-debugging` | Security incidents trigger debugging workflow |
260
261---
262
263## Skill Type
264
265**FLEXIBLE** — Adapt the depth of review to the change type using the decision table. The OWASP checklist and STRIDE analysis are strongly recommended for any auth or input-handling changes. Secrets management rules are non-negotiable.