Security Audit
Perform a comprehensive security audit of a repository based on industry-standard methodologies (OWASP, SANS, CWE). Find vulnerabilities, misconfigurations, and security anti-patterns. Optionally create GitHub issues for critical findings.
Step 0 — Determine target
If the user provided a GitHub URL, extract owner/repo.
If a local path, use directly.
If neither, use current working directory.
Ask: "Should I create GitHub issues for critical/high findings?" if not specified.
Step 1 — Reconnaissance
Understand the application before attacking:
- Identify stack: language, framework, database, cloud provider
- Map attack surface: endpoints, auth mechanisms, file uploads, external integrations
- Read configs:
docker-compose.yml, Dockerfile, .env.example, CI/CD files, IaC templates
- Identify entry points: API routes, CLI commands, event handlers, WebSocket endpoints
- Check dependencies:
requirements.txt, package.json, Cargo.toml, go.mod
Output: brief summary of stack, architecture, and attack surface.
Step 2 — Dependency Analysis
2.1 Known Vulnerabilities
# Python
gh api repos/<owner>/<repo>/dependabot/alerts --jq '.[] | select(.state=="open")'
# Or locally:
pip audit / safety check / poetry show --outdated
# Node
npm audit --json / yarn audit --json
# Go
govulncheck ./...
2.2 Supply Chain Risks
Check for:
- Typosquatting packages (names similar to popular packages)
- Pinned vs unpinned versions
- Lock file presence and integrity
- Private registry configs exposed
- Post-install scripts in dependencies
Step 3 — Secrets & Sensitive Data
Scan for hardcoded secrets:
Patterns to search
| Type |
Regex Pattern |
| AWS Keys |
AKIA[0-9A-Z]{16} |
| Generic API Key |
[aA][pP][iI][-_]?[kK][eE][yY].*['"][0-9a-zA-Z]{20,}['"] |
| JWT Secret |
`(jwt |
| Private Key |
`-----BEGIN (RSA |
| Password in code |
`(password |
| Connection strings |
`(mongodb |
| Tokens |
`(token |
| Stripe keys |
`sk_(live |
| GitHub tokens |
gh[pousr]_[A-Za-z0-9_]{36,} |
Files to check
.env, .env.* (should be in .gitignore)
- Config files committed to repo
- Test fixtures with real credentials
- CI/CD pipeline files (secrets in plain text)
- Dockerfile with ARG/ENV secrets
git log for previously committed secrets
Step 4 — Authentication & Session Management
4.1 Auth Flaws
| Vulnerability |
What to look for |
| Weak password policy |
No min length, no complexity, no bcrypt/argon2 |
| Missing rate limiting |
Login/signup/reset without throttle |
| Token issues |
No expiration, weak secret, algorithm confusion (none/HS256) |
| Session fixation |
Session ID not rotated after login |
| Credential stuffing |
No account lockout, no CAPTCHA |
| Email enumeration |
Different responses for existing/non-existing users |
| Password reset flaws |
Predictable tokens, no expiration, token reuse |
| OAuth misconfig |
Missing state param, open redirect in callback |
| 2FA bypass |
Backup codes predictable, no brute-force protection |
4.2 JWT Specific
- Algorithm set to
none accepted?
- HMAC key brute-forceable (short/common)?
- No
exp claim?
- Secret in source code?
kid parameter injection?
- JWK/JWKS injection?
Step 5 — Authorization & Access Control
| Vulnerability |
What to look for |
| IDOR |
Sequential IDs in URLs without ownership check |
| Privilege escalation |
Role checks missing on sensitive endpoints |
| Broken object-level auth |
User A accessing User B resources |
| Missing function-level auth |
Admin endpoints without role guard |
| Mass assignment |
Accepting role, is_admin, credits from request body |
| Path traversal |
../ in file paths not sanitized |
| Forced browsing |
Hidden endpoints accessible without auth |
Code patterns to flag
# IDOR - no ownership check
@app.get("/users/{user_id}/data")
def get_data(user_id: int):
return db.query(User).get(user_id) # WHO is requesting?
# Mass assignment
user.update(**request.json) # Accepts ANY field including role
Step 6 — Injection Attacks
6.1 SQL Injection
# VULNERABLE - string formatting
query = f"SELECT * FROM users WHERE id = {user_input}"
cursor.execute(f"DELETE FROM {table} WHERE id = %s") # table name injection
# SAFE - parameterized
cursor.execute("SELECT * FROM users WHERE id = %s", (user_input,))
Look for: raw SQL with string interpolation, ORM .extra(), .raw(), dynamic table/column names.
6.2 Command Injection
# VULNERABLE
os.system(f"ping {user_input}")
subprocess.call(f"convert {filename} output.png", shell=True)
# SAFE
subprocess.run(["ping", user_input], shell=False)
Look for: os.system, subprocess with shell=True, eval(), exec(), backticks in any language.
6.3 Template Injection (SSTI)
# VULNERABLE - Jinja2
template = Template(user_input) # User controls template
render_template_string(user_input)
# SAFE
render_template("fixed_template.html", data=user_input)
6.4 XSS (Cross-Site Scripting)
innerHTML, dangerouslySetInnerHTML, v-html
- Unescaped template variables:
{!! $var !!}, <%- var %>
- Reflected input in HTML without encoding
- DOM-based XSS via
document.location, window.name
6.5 LDAP / NoSQL / GraphQL Injection
- MongoDB:
$where, $regex, $gt from user input
- GraphQL: introspection enabled in prod, no depth/complexity limits
- LDAP: unescaped
(cn={input}) filters
Step 7 — API Security
| Check |
Description |
| Rate limiting |
Missing or bypassable (per-IP vs per-user) |
| Input validation |
Missing max length, type coercion, nested depth |
| Error disclosure |
Stack traces, SQL errors, internal paths in responses |
| CORS |
Access-Control-Allow-Origin: * with credentials |
| Content-Type |
No validation, accepts unexpected types |
| Pagination |
No max limit (DoS via ?limit=999999) |
| Batch/GraphQL |
No query complexity limits |
| Versioning |
Old API versions still active with known vulns |
| HTTPS |
HTTP allowed, no HSTS header |
| CSP |
Missing or unsafe-inline/unsafe-eval |
Step 8 — Cryptography
| Vulnerability |
What to look for |
| Weak hashing |
MD5, SHA1 for passwords (use bcrypt/argon2/scrypt) |
| ECB mode |
AES-ECB (use CBC/GCM with random IV) |
| Hardcoded keys |
Encryption keys in source code |
| Weak randomness |
Math.random(), random.random() for security (use secrets) |
| No salt |
Hashing without unique salt per entry |
| Broken TLS |
Accepting TLS 1.0/1.1, self-signed certs in prod |
| Key derivation |
Direct use of password as key (use PBKDF2/Argon2) |
Step 9 — Infrastructure & Configuration
9.1 Docker
- Running as root (
USER directive missing)
- Secrets in build args
latest tag (unpinned)
- Exposed debug ports
- No health check
- Writable filesystem when unnecessary
9.2 CI/CD
- Secrets in plain text in workflow files
pull_request_target with checkout of PR code (code injection)
- No branch protection on main
- Artifacts with sensitive data
- Self-hosted runners without isolation
9.3 Cloud (AWS/GCP/Azure)
- S3 buckets public
- IAM policies with
* resource
- Security groups with
0.0.0.0/0 on non-HTTP ports
- Lambda with excessive permissions
- No encryption at rest
- CloudTrail/audit logging disabled
9.4 Database
- Default credentials
- No connection encryption
- Exposed to internet
- No query timeout
- Missing indexes on auth tables (timing attacks)
Step 10 — Business Logic
| Vulnerability |
What to look for |
| Race conditions |
TOCTOU in balance/credit operations |
| Price manipulation |
Client-side price sent to server |
| Flow bypass |
Skip steps in multi-step process |
| Abuse of features |
Unlimited free tier, referral abuse |
| Integer overflow |
Negative quantities, MAX_INT amounts |
| Replay attacks |
No idempotency keys on mutations |
Step 11 — File Operations
| Vulnerability |
What to look for |
| Unrestricted upload |
No extension/MIME validation, no size limit |
| Path traversal |
../ in filenames not stripped |
| Zip slip |
Archive extraction without path validation |
| XXE |
XML parsing with external entities enabled |
| SSRF |
User-supplied URLs fetched server-side without allowlist |
| Symlink attacks |
Following symlinks in temp/upload dirs |
Step 12 — Scoring & Report
Severity Classification (CVSS-inspired)
| Severity |
Score |
Criteria |
| Critical |
9.0-10.0 |
RCE, auth bypass, full data breach, supply chain |
| High |
7.0-8.9 |
SQLi, stored XSS, IDOR on sensitive data, privilege escalation |
| Medium |
4.0-6.9 |
CSRF, reflected XSS, info disclosure, missing rate limit |
| Low |
0.1-3.9 |
Missing headers, verbose errors, minor misconfig |
| Info |
0.0 |
Best practice not followed, no direct exploit |
Output Format
For each finding:
## [SEVERITY] Title
**Category:** OWASP A01-A10 / CWE-XXX
**Location:** `file:line`
**Impact:** What an attacker can do
**Proof:** Code snippet showing the vulnerability
**Fix:** Remediation with code example
**References:** Links to relevant docs/standards
Step 13 — Final Report
# Security Audit Report
**Repository:** owner/repo
**Date:** YYYY-MM-DD
## Executive Summary
- Critical: N
- High: N
- Medium: N
- Low: N
- Total findings: N
## Findings
[List all findings sorted by severity]
## Recommendations
[Prioritized action items]
## Methodology
Based on:
- OWASP Testing Guide v4.2
- OWASP Top 10 (2021)
- CWE Top 25
- SANS Top 25
- PTES (Penetration Testing Execution Standard)
Guidelines
- Never exploit — only identify and document
- No false positives — only flag code YOU can confirm is vulnerable
- Context matters — internal tools have different risk profiles than public APIs
- Check git history — secrets may have been committed and removed
- Prioritize — focus on what's exploitable, not theoretical
- Be specific — include file:line, code snippet, and concrete fix
- Reference standards — CWE, OWASP, CVE when applicable
- Run agents in parallel for Steps 3-11 when possible to maximize efficiency
Quick Reference — OWASP Top 10 (2021)
| # |
Category |
Key checks |
| A01 |
Broken Access Control |
IDOR, missing auth, CORS, path traversal |
| A02 |
Cryptographic Failures |
Weak hash, plaintext secrets, bad TLS |
| A03 |
Injection |
SQLi, XSS, command, template, LDAP |
| A04 |
Insecure Design |
Missing threat model, no rate limit by design |
| A05 |
Security Misconfiguration |
Debug on, default creds, unnecessary features |
| A06 |
Vulnerable Components |
Outdated deps, known CVEs, no updates |
| A07 |
Auth Failures |
Weak passwords, no MFA, credential stuffing |
| A08 |
Software/Data Integrity |
Deserialization, CI/CD tampering, unsigned updates |
| A09 |
Logging Failures |
No audit log, sensitive data in logs, no alerting |
| A10 |
SSRF |
Unvalidated URLs, internal service access |
1---2name: security-audit3description: Security audit skill for repositories. Use when the user asks to 'audit security', 'pentest repo', 'find vulnerabilities', 'security review', 'check for exploits', 'OWASP check', or wants a comprehensive security analysis of a codebase. Covers OWASP Top 10, dependency vulnerabilities, secrets detection, auth/authz flaws, injection vectors, and infrastructure misconfigurations.4---56# Security Audit78Perform a comprehensive security audit of a repository based on industry-standard methodologies (OWASP, SANS, CWE). Find vulnerabilities, misconfigurations, and security anti-patterns. Optionally create GitHub issues for critical findings.910---1112## Step 0 — Determine target1314If the user provided a GitHub URL, extract `owner/repo`.15If a local path, use directly.16If neither, use current working directory.1718Ask: **"Should I create GitHub issues for critical/high findings?"** if not specified.1920---2122## Step 1 — Reconnaissance2324Understand the application before attacking:25261. **Identify stack**: language, framework, database, cloud provider272. **Map attack surface**: endpoints, auth mechanisms, file uploads, external integrations283. **Read configs**: `docker-compose.yml`, `Dockerfile`, `.env.example`, CI/CD files, IaC templates294. **Identify entry points**: API routes, CLI commands, event handlers, WebSocket endpoints305. **Check dependencies**: `requirements.txt`, `package.json`, `Cargo.toml`, `go.mod`3132Output: brief summary of stack, architecture, and attack surface.3334---3536## Step 2 — Dependency Analysis3738### 2.1 Known Vulnerabilities3940```bash41# Python42gh api repos/<owner>/<repo>/dependabot/alerts --jq '.[] | select(.state=="open")'43# Or locally:44pip audit / safety check / poetry show --outdated4546# Node47npm audit --json / yarn audit --json4849# Go50govulncheck ./...51```5253### 2.2 Supply Chain Risks5455Check for:56- Typosquatting packages (names similar to popular packages)57- Pinned vs unpinned versions58- Lock file presence and integrity59- Private registry configs exposed60- Post-install scripts in dependencies6162---6364## Step 3 — Secrets & Sensitive Data6566Scan for hardcoded secrets:6768### Patterns to search6970| Type | Regex Pattern |71|------|--------------|72| AWS Keys | `AKIA[0-9A-Z]{16}` |73| Generic API Key | `[aA][pP][iI][-_]?[kK][eE][yY].*['"][0-9a-zA-Z]{20,}['"]` |74| JWT Secret | `(jwt|JWT|secret|SECRET).*['"][^'"]{8,}['"]` |75| Private Key | `-----BEGIN (RSA|EC|DSA|OPENSSH) PRIVATE KEY-----` |76| Password in code | `(password|passwd|pwd)\s*=\s*['"][^'"]+['"]` |77| Connection strings | `(mongodb|mysql|postgres|redis)://[^\s'"]+` |78| Tokens | `(token|TOKEN)\s*=\s*['"][0-9a-zA-Z\-_.]{20,}['"]` |79| Stripe keys | `sk_(live|test)_[0-9a-zA-Z]{24,}` |80| GitHub tokens | `gh[pousr]_[A-Za-z0-9_]{36,}` |8182### Files to check83- `.env`, `.env.*` (should be in `.gitignore`)84- Config files committed to repo85- Test fixtures with real credentials86- CI/CD pipeline files (secrets in plain text)87- Dockerfile with ARG/ENV secrets88- `git log` for previously committed secrets8990---9192## Step 4 — Authentication & Session Management9394### 4.1 Auth Flaws9596| Vulnerability | What to look for |97|---------------|-----------------|98| Weak password policy | No min length, no complexity, no bcrypt/argon2 |99| Missing rate limiting | Login/signup/reset without throttle |100| Token issues | No expiration, weak secret, algorithm confusion (none/HS256) |101| Session fixation | Session ID not rotated after login |102| Credential stuffing | No account lockout, no CAPTCHA |103| Email enumeration | Different responses for existing/non-existing users |104| Password reset flaws | Predictable tokens, no expiration, token reuse |105| OAuth misconfig | Missing state param, open redirect in callback |106| 2FA bypass | Backup codes predictable, no brute-force protection |107108### 4.2 JWT Specific109110- Algorithm set to `none` accepted?111- HMAC key brute-forceable (short/common)?112- No `exp` claim?113- Secret in source code?114- `kid` parameter injection?115- JWK/JWKS injection?116117---118119## Step 5 — Authorization & Access Control120121| Vulnerability | What to look for |122|---------------|-----------------|123| IDOR | Sequential IDs in URLs without ownership check |124| Privilege escalation | Role checks missing on sensitive endpoints |125| Broken object-level auth | User A accessing User B resources |126| Missing function-level auth | Admin endpoints without role guard |127| Mass assignment | Accepting `role`, `is_admin`, `credits` from request body |128| Path traversal | `../` in file paths not sanitized |129| Forced browsing | Hidden endpoints accessible without auth |130131### Code patterns to flag132133```python134# IDOR - no ownership check135@app.get("/users/{user_id}/data")136def get_data(user_id: int):137 return db.query(User).get(user_id) # WHO is requesting?138139# Mass assignment140user.update(**request.json) # Accepts ANY field including role141```142143---144145## Step 6 — Injection Attacks146147### 6.1 SQL Injection148149```python150# VULNERABLE - string formatting151query = f"SELECT * FROM users WHERE id = {user_input}"152cursor.execute(f"DELETE FROM {table} WHERE id = %s") # table name injection153154# SAFE - parameterized155cursor.execute("SELECT * FROM users WHERE id = %s", (user_input,))156```157158Look for: raw SQL with string interpolation, ORM `.extra()`, `.raw()`, dynamic table/column names.159160### 6.2 Command Injection161162```python163# VULNERABLE164os.system(f"ping {user_input}")165subprocess.call(f"convert {filename} output.png", shell=True)166167# SAFE168subprocess.run(["ping", user_input], shell=False)169```170171Look for: `os.system`, `subprocess` with `shell=True`, `eval()`, `exec()`, backticks in any language.172173### 6.3 Template Injection (SSTI)174175```python176# VULNERABLE - Jinja2177template = Template(user_input) # User controls template178render_template_string(user_input)179180# SAFE181render_template("fixed_template.html", data=user_input)182```183184### 6.4 XSS (Cross-Site Scripting)185186- `innerHTML`, `dangerouslySetInnerHTML`, `v-html`187- Unescaped template variables: `{!! $var !!}`, `<%- var %>`188- Reflected input in HTML without encoding189- DOM-based XSS via `document.location`, `window.name`190191### 6.5 LDAP / NoSQL / GraphQL Injection192193- MongoDB: `$where`, `$regex`, `$gt` from user input194- GraphQL: introspection enabled in prod, no depth/complexity limits195- LDAP: unescaped `(cn={input})` filters196197---198199## Step 7 — API Security200201| Check | Description |202|-------|-------------|203| Rate limiting | Missing or bypassable (per-IP vs per-user) |204| Input validation | Missing max length, type coercion, nested depth |205| Error disclosure | Stack traces, SQL errors, internal paths in responses |206| CORS | `Access-Control-Allow-Origin: *` with credentials |207| Content-Type | No validation, accepts unexpected types |208| Pagination | No max limit (DoS via `?limit=999999`) |209| Batch/GraphQL | No query complexity limits |210| Versioning | Old API versions still active with known vulns |211| HTTPS | HTTP allowed, no HSTS header |212| CSP | Missing or `unsafe-inline`/`unsafe-eval` |213214---215216## Step 8 — Cryptography217218| Vulnerability | What to look for |219|---------------|-----------------|220| Weak hashing | MD5, SHA1 for passwords (use bcrypt/argon2/scrypt) |221| ECB mode | AES-ECB (use CBC/GCM with random IV) |222| Hardcoded keys | Encryption keys in source code |223| Weak randomness | `Math.random()`, `random.random()` for security (use `secrets`) |224| No salt | Hashing without unique salt per entry |225| Broken TLS | Accepting TLS 1.0/1.1, self-signed certs in prod |226| Key derivation | Direct use of password as key (use PBKDF2/Argon2) |227228---229230## Step 9 — Infrastructure & Configuration231232### 9.1 Docker233234- Running as root (`USER` directive missing)235- Secrets in build args236- `latest` tag (unpinned)237- Exposed debug ports238- No health check239- Writable filesystem when unnecessary240241### 9.2 CI/CD242243- Secrets in plain text in workflow files244- `pull_request_target` with checkout of PR code (code injection)245- No branch protection on main246- Artifacts with sensitive data247- Self-hosted runners without isolation248249### 9.3 Cloud (AWS/GCP/Azure)250251- S3 buckets public252- IAM policies with `*` resource253- Security groups with `0.0.0.0/0` on non-HTTP ports254- Lambda with excessive permissions255- No encryption at rest256- CloudTrail/audit logging disabled257258### 9.4 Database259260- Default credentials261- No connection encryption262- Exposed to internet263- No query timeout264- Missing indexes on auth tables (timing attacks)265266---267268## Step 10 — Business Logic269270| Vulnerability | What to look for |271|---------------|-----------------|272| Race conditions | TOCTOU in balance/credit operations |273| Price manipulation | Client-side price sent to server |274| Flow bypass | Skip steps in multi-step process |275| Abuse of features | Unlimited free tier, referral abuse |276| Integer overflow | Negative quantities, MAX_INT amounts |277| Replay attacks | No idempotency keys on mutations |278279---280281## Step 11 — File Operations282283| Vulnerability | What to look for |284|---------------|-----------------|285| Unrestricted upload | No extension/MIME validation, no size limit |286| Path traversal | `../` in filenames not stripped |287| Zip slip | Archive extraction without path validation |288| XXE | XML parsing with external entities enabled |289| SSRF | User-supplied URLs fetched server-side without allowlist |290| Symlink attacks | Following symlinks in temp/upload dirs |291292---293294## Step 12 — Scoring & Report295296### Severity Classification (CVSS-inspired)297298| Severity | Score | Criteria |299|----------|-------|----------|300| Critical | 9.0-10.0 | RCE, auth bypass, full data breach, supply chain |301| High | 7.0-8.9 | SQLi, stored XSS, IDOR on sensitive data, privilege escalation |302| Medium | 4.0-6.9 | CSRF, reflected XSS, info disclosure, missing rate limit |303| Low | 0.1-3.9 | Missing headers, verbose errors, minor misconfig |304| Info | 0.0 | Best practice not followed, no direct exploit |305306### Output Format307308For each finding:309310```markdown311## [SEVERITY] Title312313**Category:** OWASP A01-A10 / CWE-XXX314**Location:** `file:line`315**Impact:** What an attacker can do316**Proof:** Code snippet showing the vulnerability317**Fix:** Remediation with code example318**References:** Links to relevant docs/standards319```320321---322323## Step 13 — Final Report324325```markdown326# Security Audit Report327328**Repository:** owner/repo329**Date:** YYYY-MM-DD330331## Executive Summary332333- Critical: N334- High: N335- Medium: N336- Low: N337- Total findings: N338339## Findings340341[List all findings sorted by severity]342343## Recommendations344345[Prioritized action items]346347## Methodology348349Based on:350- OWASP Testing Guide v4.2351- OWASP Top 10 (2021)352- CWE Top 25353- SANS Top 25354- PTES (Penetration Testing Execution Standard)355```356357---358359## Guidelines360361- **Never exploit** — only identify and document362- **No false positives** — only flag code YOU can confirm is vulnerable363- **Context matters** — internal tools have different risk profiles than public APIs364- **Check git history** — secrets may have been committed and removed365- **Prioritize** — focus on what's exploitable, not theoretical366- **Be specific** — include file:line, code snippet, and concrete fix367- **Reference standards** — CWE, OWASP, CVE when applicable368- Run agents in parallel for Steps 3-11 when possible to maximize efficiency369370---371372## Quick Reference — OWASP Top 10 (2021)373374| # | Category | Key checks |375|---|----------|-----------|376| A01 | Broken Access Control | IDOR, missing auth, CORS, path traversal |377| A02 | Cryptographic Failures | Weak hash, plaintext secrets, bad TLS |378| A03 | Injection | SQLi, XSS, command, template, LDAP |379| A04 | Insecure Design | Missing threat model, no rate limit by design |380| A05 | Security Misconfiguration | Debug on, default creds, unnecessary features |381| A06 | Vulnerable Components | Outdated deps, known CVEs, no updates |382| A07 | Auth Failures | Weak passwords, no MFA, credential stuffing |383| A08 | Software/Data Integrity | Deserialization, CI/CD tampering, unsigned updates |384| A09 | Logging Failures | No audit log, sensitive data in logs, no alerting |385| A10 | SSRF | Unvalidated URLs, internal service access |