| name | security-review |
| description | Security review checklists, threat model, severity classification, and supply chain verification for Java/Spring Boot applications. Load when conducting security reviews. |
| compatibility | ["claude-code","github-copilot","opencode","junie-cli"] |
| metadata | {"version":"1.0","author":"team"} |
Core Security Principles
This review enforces four non-negotiable laws: security as an emergent property, defense in depth, least privilege, fail secure. They are harness-owned, defined in tdd-principles.md § Secure by Design. How this project meets them — its trust boundaries and the stack's high-bar defaults — lives in the project-owned docs/security-principles.md, the same brief the feature-implementer designs against. Read both before reviewing and enforce what they say, not remembered defaults. This skill holds the exhaustive checklist that turns the laws and defaults into specific, gradeable items.
Security Checklist
Path Traversal and File Operations
Input Injection
HTML Output Safety (if applicable)
JSON Safety
Credential and Sensitive Data Handling
Input Validation
Network Security (if applicable)
Resource Management
Dependency Security
Logging Safety
Java-Specific Security Checks
Concurrency Safety
Error Handling
Type Safety
IDE-Assisted Checks (optional)
When an IDE semantic oracle is available, use it to complement (never replace) the Grep patterns above: check the resolved dependency set for the Dependency Security checklist, and answer access-control / route-exposure questions by resolving security-relevant symbols and their references rather than text-matching config. The latter is required, not optional: when the oracle is connected, an access-control / route-exposure claim that turns on how a symbol or its references resolve (e.g. "this endpoint is the only unauthenticated caller", "the filter chain covers this route") must cite the search_symbol / get_symbol_info call that backs it (see intellij-idea § Cite the call that backs a claim) — without the oracle, cite the grep and label it the weaker basis. The resolved-dependency check stays an accelerator; a client without an oracle relies on Grep alone. Tool mechanics — and the Actuator alternative for the live bean/route graph — live in the intellij-idea skill.
Severity Classification
Rate by reachability and the harm an attacker gains, not by which bucket the issue's name suggests. Severity drives the blocked gate, so a reachable medium outranks an unreachable critical.
CRITICAL (BLOCKED)
- Credential exposure in logs or errors
- Remote code execution vectors (unsafe Jackson deserialization, shell injection)
- Authentication bypass
- Unvalidated external input to sensitive operations
HIGH (BLOCKED)
- Path traversal allowing writes outside designated directories
- Missing input validation on external data
- Unbounded memory allocation (response size limits)
- File handles leaked (no try-with-resources)
- ReDoS-vulnerable regex patterns
MEDIUM
- Sensitive data in verbose error messages
- Missing timeouts on network operations
- Missing Content-Security-Policy in generated HTML
- Verbose logging in production default
LOW
- Information disclosure in health endpoints
- Missing rate limiting
- Dependency not on latest patch version
Detection Patterns
Use Grep to search for dangerous code patterns during review:
| Pattern | What It Detects |
|---|
append|concat|format|printf|+.*html|\.write( in src/main/java/ | Unescaped output |
Runtime|ProcessBuilder|exec( in src/main/java/ | Shell execution |
enableDefaultTyping|JsonTypeInfo|WRAPPER_ARRAY in src/main/java/ | Unsafe Jackson config |
Files\.|FileWriter|FileOutputStream|BufferedWriter in src/main/java/ | File operations |
followLinks|NOFOLLOW in src/main/java/ | Symlink handling |
/tmp/ in src/main/java/ | System tmp usage (should use .scratch/tmp/) |
Supply Chain Verification
Run the dependency check when the project configures it:
./gradlew dependencyCheckAnalyze
./gradlew dependencies
dependencyCheckAnalyze matches resolved artifacts against the NVD; judge each finding by reachability per § Severity Classification, not by raw score. Without the plugin, no NVD match runs in this review — the reviewer has no network access. Instead, read the framework versions (Spring Boot, Jackson) from the dependencies output and report them under a "not verified against the NVD" finding, so a human or CI closes the check. Report only checks that actually ran — an un-run check is "not run", never clean.