Skip to content

Commit 7e375ea

Browse files
authored
feat: add security-review skill for AI-powered codebase vulnerability scanning (#1211)
* feat: add security-review skill for AI-powered codebase vulnerability scanning * chore: regenerate README tables * fix: address Copilot review comments on reference files
1 parent 04a7e6c commit 7e375ea

7 files changed

Lines changed: 1154 additions & 0 deletions

File tree

docs/README.skills.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-skills) for guidelines on how to
241241
| [scaffolding-oracle-to-postgres-migration-test-project](../skills/scaffolding-oracle-to-postgres-migration-test-project/SKILL.md) | Scaffolds an xUnit integration test project for validating Oracle-to-PostgreSQL database migration behavior in .NET solutions. Creates the test project, transaction-rollback base class, and seed data manager. Use when setting up test infrastructure before writing migration integration tests, or when a test project is needed for Oracle-to-PostgreSQL validation. | None |
242242
| [scoutqa-test](../skills/scoutqa-test/SKILL.md) | This skill should be used when the user asks to "test this website", "run exploratory testing", "check for accessibility issues", "verify the login flow works", "find bugs on this page", or requests automated QA testing. Triggers on web application testing scenarios including smoke tests, accessibility audits, e-commerce flows, and user flow validation using ScoutQA CLI. Use this skill proactively after implementing web application features to verify they work correctly. | None |
243243
| [secret-scanning](../skills/secret-scanning/SKILL.md) | Guide for configuring and managing GitHub secret scanning, push protection, custom patterns, and secret alert remediation. For pre-commit secret scanning in AI coding agents via the GitHub MCP Server, this skill references the Advanced Security plugin (`advanced-security@copilot-plugins`). Use this skill when enabling secret scanning, setting up push protection, defining custom patterns, triaging alerts, resolving blocked pushes, or when an agent needs to scan code for secrets before committing. | `references/alerts-and-remediation.md`<br />`references/custom-patterns.md`<br />`references/push-protection.md` |
244+
| [security-review](../skills/security-review/SKILL.md) | AI-powered codebase security scanner that reasons about code like a security researcher — tracing data flows, understanding component interactions, and catching vulnerabilities that pattern-matching tools miss. Use this skill when asked to scan code for security vulnerabilities, find bugs, check for SQL injection, XSS, command injection, exposed API keys, hardcoded secrets, insecure dependencies, access control issues, or any request like "is my code secure?", "review for security issues", "audit this codebase", or "check for vulnerabilities". Covers injection flaws, authentication and access control bugs, secrets exposure, weak cryptography, insecure dependencies, and business logic issues across JavaScript, TypeScript, Python, Java, PHP, Go, Ruby, and Rust. | `references/language-patterns.md`<br />`references/report-format.md`<br />`references/secret-patterns.md`<br />`references/vuln-categories.md`<br />`references/vulnerable-packages.md` |
244245
| [semantic-kernel](../skills/semantic-kernel/SKILL.md) | Create, update, refactor, explain, or review Semantic Kernel solutions using shared guidance plus language-specific references for .NET and Python. | `references/dotnet.md`<br />`references/python.md` |
245246
| [shuffle-json-data](../skills/shuffle-json-data/SKILL.md) | Shuffle repetitive JSON objects safely by validating schema consistency before randomising entries. | None |
246247
| [snowflake-semanticview](../skills/snowflake-semanticview/SKILL.md) | Create, alter, and validate Snowflake semantic views using Snowflake CLI (snow). Use when asked to build or troubleshoot semantic views/semantic layer definitions with CREATE/ALTER SEMANTIC VIEW, to validate semantic-view DDL against Snowflake via CLI, or to guide Snowflake CLI installation and connection setup. | None |

skills/security-review/SKILL.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
---
2+
name: security-review
3+
description: 'AI-powered codebase security scanner that reasons about code like a security researcher — tracing data flows, understanding component interactions, and catching vulnerabilities that pattern-matching tools miss. Use this skill when asked to scan code for security vulnerabilities, find bugs, check for SQL injection, XSS, command injection, exposed API keys, hardcoded secrets, insecure dependencies, access control issues, or any request like "is my code secure?", "review for security issues", "audit this codebase", or "check for vulnerabilities". Covers injection flaws, authentication and access control bugs, secrets exposure, weak cryptography, insecure dependencies, and business logic issues across JavaScript, TypeScript, Python, Java, PHP, Go, Ruby, and Rust.'
4+
---
5+
6+
# Security Review
7+
8+
An AI-powered security scanner that reasons about your codebase the way a human security
9+
researcher would — tracing data flows, understanding component interactions, and catching
10+
vulnerabilities that pattern-matching tools miss.
11+
12+
## When to Use This Skill
13+
14+
Use this skill when the request involves:
15+
16+
- Scanning a codebase or file for security vulnerabilities
17+
- Running a security review or vulnerability check
18+
- Checking for SQL injection, XSS, command injection, or other injection flaws
19+
- Finding exposed API keys, hardcoded secrets, or credentials in code
20+
- Auditing dependencies for known CVEs
21+
- Reviewing authentication, authorization, or access control logic
22+
- Detecting insecure cryptography or weak randomness
23+
- Performing a data flow analysis to trace user input to dangerous sinks
24+
- Any request phrasing like "is my code secure?", "scan this file", or "check my repo for vulnerabilities"
25+
- Running `/security-review` or `/security-review <path>`
26+
27+
## How This Skill Works
28+
29+
Unlike traditional static analysis tools that match patterns, this skill:
30+
1. **Reads code like a security researcher** — understanding context, intent, and data flow
31+
2. **Traces across files** — following how user input moves through your application
32+
3. **Self-verifies findings** — re-examines each result to filter false positives
33+
4. **Assigns severity ratings** — CRITICAL / HIGH / MEDIUM / LOW / INFO
34+
5. **Proposes targeted patches** — every finding includes a concrete fix
35+
6. **Requires human approval** — nothing is auto-applied; you always review first
36+
37+
## Execution Workflow
38+
39+
Follow these steps **in order** every time:
40+
41+
### Step 1 — Scope Resolution
42+
Determine what to scan:
43+
- If a path was provided (`/security-review src/auth/`), scan only that scope
44+
- If no path given, scan the **entire project** starting from the root
45+
- Identify the language(s) and framework(s) in use (check package.json, requirements.txt,
46+
go.mod, Cargo.toml, pom.xml, Gemfile, composer.json, etc.)
47+
- Read `references/language-patterns.md` to load language-specific vulnerability patterns
48+
49+
### Step 2 — Dependency Audit
50+
Before scanning source code, audit dependencies first (fast wins):
51+
- **Node.js**: Check `package.json` + `package-lock.json` for known vulnerable packages
52+
- **Python**: Check `requirements.txt` / `pyproject.toml` / `Pipfile`
53+
- **Java**: Check `pom.xml` / `build.gradle`
54+
- **Ruby**: Check `Gemfile.lock`
55+
- **Rust**: Check `Cargo.toml`
56+
- **Go**: Check `go.sum`
57+
- Flag packages with known CVEs, deprecated crypto libs, or suspiciously old pinned versions
58+
- Read `references/vulnerable-packages.md` for a curated watchlist
59+
60+
### Step 3 — Secrets & Exposure Scan
61+
Scan ALL files (including config, env, CI/CD, Dockerfiles, IaC) for:
62+
- Hardcoded API keys, tokens, passwords, private keys
63+
- `.env` files accidentally committed
64+
- Secrets in comments or debug logs
65+
- Cloud credentials (AWS, GCP, Azure, Stripe, Twilio, etc.)
66+
- Database connection strings with credentials embedded
67+
- Read `references/secret-patterns.md` for regex patterns and entropy heuristics to apply
68+
69+
### Step 4 — Vulnerability Deep Scan
70+
This is the core scan. Reason about the code — don't just pattern-match.
71+
Read `references/vuln-categories.md` for full details on each category.
72+
73+
**Injection Flaws**
74+
- SQL Injection: raw queries with string interpolation, ORM misuse, second-order SQLi
75+
- XSS: unescaped output, dangerouslySetInnerHTML, innerHTML, template injection
76+
- Command Injection: exec/spawn/system with user input
77+
- LDAP, XPath, Header, Log injection
78+
79+
**Authentication & Access Control**
80+
- Missing authentication on sensitive endpoints
81+
- Broken object-level authorization (BOLA/IDOR)
82+
- JWT weaknesses (alg:none, weak secrets, no expiry validation)
83+
- Session fixation, missing CSRF protection
84+
- Privilege escalation paths
85+
- Mass assignment / parameter pollution
86+
87+
**Data Handling**
88+
- Sensitive data in logs, error messages, or API responses
89+
- Missing encryption at rest or in transit
90+
- Insecure deserialization
91+
- Path traversal / directory traversal
92+
- XXE (XML External Entity) processing
93+
- SSRF (Server-Side Request Forgery)
94+
95+
**Cryptography**
96+
- Use of MD5, SHA1, DES for security purposes
97+
- Hardcoded IVs or salts
98+
- Weak random number generation (Math.random() for tokens)
99+
- Missing TLS certificate validation
100+
101+
**Business Logic**
102+
- Race conditions (TOCTOU)
103+
- Integer overflow in financial calculations
104+
- Missing rate limiting on sensitive endpoints
105+
- Predictable resource identifiers
106+
107+
### Step 5 — Cross-File Data Flow Analysis
108+
After the per-file scan, perform a **holistic review**:
109+
- Trace user-controlled input from entry points (HTTP params, headers, body, file uploads)
110+
all the way to sinks (DB queries, exec calls, HTML output, file writes)
111+
- Identify vulnerabilities that only appear when looking at multiple files together
112+
- Check for insecure trust boundaries between services or modules
113+
114+
### Step 6 — Self-Verification Pass
115+
For EACH finding:
116+
1. Re-read the relevant code with fresh eyes
117+
2. Ask: "Is this actually exploitable, or is there sanitization I missed?"
118+
3. Check if a framework or middleware already handles this upstream
119+
4. Downgrade or discard findings that aren't genuine vulnerabilities
120+
5. Assign final severity: CRITICAL / HIGH / MEDIUM / LOW / INFO
121+
122+
### Step 7 — Generate Security Report
123+
Output the full report in the format defined in `references/report-format.md`.
124+
125+
### Step 8 — Propose Patches
126+
For every CRITICAL and HIGH finding, generate a concrete patch:
127+
- Show the vulnerable code (before)
128+
- Show the fixed code (after)
129+
- Explain what changed and why
130+
- Preserve the original code style, variable names, and structure
131+
- Add a comment explaining the fix inline
132+
133+
Explicitly state: **"Review each patch before applying. Nothing has been changed yet."**
134+
135+
## Severity Guide
136+
137+
| Severity | Meaning | Example |
138+
|----------|---------|---------|
139+
| 🔴 CRITICAL | Immediate exploitation risk, data breach likely | SQLi, RCE, auth bypass |
140+
| 🟠 HIGH | Serious vulnerability, exploit path exists | XSS, IDOR, hardcoded secrets |
141+
| 🟡 MEDIUM | Exploitable with conditions or chaining | CSRF, open redirect, weak crypto |
142+
| 🔵 LOW | Best practice violation, low direct risk | Verbose errors, missing headers |
143+
| ⚪ INFO | Observation worth noting, not a vulnerability | Outdated dependency (no CVE) |
144+
145+
## Output Rules
146+
147+
- **Always** produce a findings summary table first (counts by severity)
148+
- **Never** auto-apply any patch — present patches for human review only
149+
- **Always** include a confidence rating per finding (High / Medium / Low)
150+
- **Group findings** by category, not by file
151+
- **Be specific** — include file path, line number, and the exact vulnerable code snippet
152+
- **Explain the risk** in plain English — what could an attacker do with this?
153+
- If the codebase is clean, say so clearly: "No vulnerabilities found" with what was scanned
154+
155+
## Reference Files
156+
157+
For detailed detection guidance, load the following reference files as needed:
158+
159+
- `references/vuln-categories.md` — Deep reference for every vulnerability category with detection signals, safe patterns, and escalation checkers
160+
- Search patterns: `SQL injection`, `XSS`, `command injection`, `SSRF`, `BOLA`, `IDOR`, `JWT`, `CSRF`, `secrets`, `cryptography`, `race condition`, `path traversal`
161+
- `references/secret-patterns.md` — Regex patterns, entropy-based detection, and CI/CD secret risks
162+
- Search patterns: `API key`, `token`, `private key`, `connection string`, `entropy`, `.env`, `GitHub Actions`, `Docker`, `Terraform`
163+
- `references/language-patterns.md` — Framework-specific vulnerability patterns for JavaScript, Python, Java, PHP, Go, Ruby, and Rust
164+
- Search patterns: `Express`, `React`, `Next.js`, `Django`, `Flask`, `FastAPI`, `Spring Boot`, `PHP`, `Go`, `Rails`, `Rust`
165+
- `references/vulnerable-packages.md` — Curated CVE watchlist for npm, pip, Maven, Rubygems, Cargo, and Go modules
166+
- Search patterns: `lodash`, `axios`, `jsonwebtoken`, `Pillow`, `log4j`, `nokogiri`, `CVE`
167+
- `references/report-format.md` — Structured output template for security reports with finding cards, dependency audit, secrets scan, and patch proposal formatting
168+
- Search patterns: `report`, `format`, `template`, `finding`, `patch`, `summary`, `confidence`
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# Language-Specific Vulnerability Patterns
2+
3+
Load the relevant section during Step 1 (Scope Resolution) after identifying languages.
4+
5+
---
6+
7+
## JavaScript / TypeScript (Node.js, React, Next.js, Express)
8+
9+
### Critical APIs/calls to flag
10+
```js
11+
eval() // arbitrary code execution
12+
Function('return ...') // same as eval
13+
child_process.exec() // command injection if user input reaches it
14+
fs.readFile // path traversal if user controls path
15+
fs.writeFile // path traversal if user controls path
16+
```
17+
18+
### Express.js specific
19+
```js
20+
// Missing helmet (security headers)
21+
const app = express()
22+
// Should have: app.use(helmet())
23+
24+
// Body size limits missing (DoS)
25+
app.use(express.json())
26+
// Should have: app.use(express.json({ limit: '10kb' }))
27+
28+
// CORS misconfiguration
29+
app.use(cors({ origin: '*' })) // too permissive
30+
app.use(cors({ origin: req.headers.origin })) // reflects any origin
31+
32+
// Trust proxy without validation
33+
app.set('trust proxy', true) // only safe behind known proxy
34+
```
35+
36+
### React specific
37+
```jsx
38+
<div dangerouslySetInnerHTML={{ __html: userContent }} /> // XSS
39+
<a href={userUrl}>link</a> // javascript: URL injection
40+
```
41+
42+
### Next.js specific
43+
```js
44+
// Server Actions without auth
45+
export async function deleteUser(id) { // missing: auth check
46+
await db.users.delete(id)
47+
}
48+
49+
// API Routes missing method validation
50+
export default function handler(req, res) {
51+
// Should check: if (req.method !== 'POST') return res.status(405)
52+
doSensitiveAction()
53+
}
54+
```
55+
56+
---
57+
58+
## Python (Django, Flask, FastAPI)
59+
60+
### Django specific
61+
```python
62+
# Raw SQL
63+
User.objects.raw(f"SELECT * FROM users WHERE name = '{name}'") # SQLi
64+
65+
# Missing CSRF
66+
@csrf_exempt # Only OK for APIs with token auth
67+
68+
# Debug mode in production
69+
DEBUG = True # in settings.py — exposes stack traces
70+
71+
# SECRET_KEY
72+
SECRET_KEY = 'django-insecure-...' # must be changed for production
73+
74+
# ALLOWED_HOSTS
75+
ALLOWED_HOSTS = ['*'] # too permissive
76+
```
77+
78+
### Flask specific
79+
```python
80+
# Debug mode
81+
app.run(debug=True) # never in production
82+
83+
# Secret key
84+
app.secret_key = 'dev' # weak
85+
86+
# eval/exec with user input
87+
eval(request.args.get('expr'))
88+
89+
# render_template_string with user input (SSTI)
90+
render_template_string(f"Hello {name}") # Server-Side Template Injection
91+
```
92+
93+
### FastAPI specific
94+
```python
95+
# Missing auth dependency
96+
@app.delete("/users/{user_id}") # No Depends(get_current_user)
97+
async def delete_user(user_id: int):
98+
...
99+
100+
# Arbitrary file read
101+
@app.get("/files/{filename}")
102+
async def read_file(filename: str):
103+
return FileResponse(f"uploads/{filename}") # path traversal
104+
```
105+
106+
---
107+
108+
## Java (Spring Boot)
109+
110+
### Spring Boot specific
111+
```java
112+
// SQL Injection
113+
String query = "SELECT * FROM users WHERE name = '" + name + "'";
114+
jdbcTemplate.query(query, ...);
115+
116+
// XXE
117+
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
118+
// Missing: dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
119+
120+
// Deserialization
121+
ObjectInputStream ois = new ObjectInputStream(inputStream);
122+
Object obj = ois.readObject(); // only safe with allowlist
123+
124+
// Spring Security — permitAll on sensitive endpoint
125+
.antMatchers("/admin/**").permitAll()
126+
127+
// Actuator endpoints exposed
128+
management.endpoints.web.exposure.include=* # in application.properties
129+
```
130+
131+
---
132+
133+
## PHP
134+
135+
```php
136+
// Direct user input in queries
137+
$result = mysql_query("SELECT * FROM users WHERE id = " . $_GET['id']);
138+
139+
// File inclusion
140+
include($_GET['page'] . ".php"); // local/remote file inclusion
141+
142+
// eval
143+
eval($_POST['code']);
144+
145+
// extract() with user input
146+
extract($_POST); // overwrites any variable
147+
148+
// Loose comparison
149+
if ($password == "admin") {} // use === instead
150+
151+
// Unserialize
152+
unserialize($_COOKIE['data']); // remote code execution
153+
```
154+
155+
---
156+
157+
## Go
158+
159+
```go
160+
// Command injection
161+
exec.Command("sh", "-c", userInput)
162+
163+
// SQL injection
164+
db.Query("SELECT * FROM users WHERE name = '" + name + "'")
165+
166+
// Path traversal
167+
filePath := filepath.Join("/uploads/", userInput) // sanitize userInput first
168+
169+
// Insecure TLS
170+
http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
171+
172+
// Goroutine leak / missing context cancellation
173+
go func() {
174+
// No done channel or context
175+
for { ... }
176+
}()
177+
```
178+
179+
---
180+
181+
## Ruby on Rails
182+
183+
```ruby
184+
# SQL injection (safe alternatives use placeholders)
185+
User.where("name = '#{params[:name]}'") # VULNERABLE
186+
User.where("name = ?", params[:name]) # SAFE
187+
188+
# Mass assignment without strong params
189+
@user.update(params[:user]) # should be params.require(:user).permit(...)
190+
191+
# eval / send with user input
192+
eval(params[:code])
193+
send(params[:method]) # arbitrary method call
194+
195+
# Redirect to user-supplied URL (open redirect)
196+
redirect_to params[:url]
197+
198+
# YAML.load (allows arbitrary object creation)
199+
YAML.load(user_input) # use YAML.safe_load instead
200+
```
201+
202+
---
203+
204+
## Rust
205+
206+
```rust
207+
// Unsafe blocks — flag for manual review
208+
unsafe {
209+
// Reason for unsafety should be documented
210+
}
211+
212+
// Integer overflow (debug builds panic, release silently wraps)
213+
let result = a + b; // use checked_add/saturating_add for financial math
214+
215+
// Unwrap/expect in production code (panics on None/Err)
216+
let value = option.unwrap(); // prefer ? or match
217+
218+
// Deserializing arbitrary types
219+
serde_json::from_str::<serde_json::Value>(&user_input) // generally safe
220+
// But: bincode::deserialize from untrusted input — can be exploited
221+
```

0 commit comments

Comments
 (0)