Audit an inherited or unfamiliar codebase systematically rather than ad-hoc. Covers scope discipline, day-0 triage, SAST and SCA tool recipes (semgrep, CodeQL, gitleaks, trivy), OWASP Top 10 mapped to grep patterns, auth-surface walkthrough, and writing reports that drive remediation. Invoke when inheriting a codebase, accepting an audit engagement, or reviewing AI-generated code before shipping.
Installation
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Audit an inherited or unfamiliar codebase systematically rather than ad-hoc. Covers scope discipline, day-0 triage, SAST and SCA tool recipes (semgrep, CodeQL, gitleaks, trivy), OWASP Top 10 mapped to grep patterns, auth-surface walkthrough, and writing reports that drive remediation. Invoke when inheriting a codebase, accepting an audit engagement, or reviewing AI-generated code before shipping.
Codebase Audit — the Inherited-Code Playbook
This is the skill that binds the others together. Most engagement value from a security review comes from the auditor's process, not from any single check. A junior auditor with a great tool produces a noisy report; a senior auditor with grep and a methodology finds the things that matter.
This skill is the methodology. It walks the audit from "I just got SSH access / a repo URL" through to "here's the prioritized report with owners and deadlines." It cross-links into every hardening skill in this repo as the deep-dive material per finding class.
When to invoke
Inheriting a codebase — new job, new client, open-source fork, acquisition target
"Audit my app" engagement — freelancer / consultancy work
Onboarding to a project — you'll touch the code soon and need to know what's safe to assume
AI-generated codebase review — before shipping a Claude/Copilot/Cursor-written app
Periodic re-audit — annual review of a system you already know
Step 0 — Scope before substance
The most common reason audits fail is the auditor trying to look at everything. Scope discipline is the difference between a useful report and a 300-page document nobody reads.
Before starting, write down:
Why this audit exists — diligence? incident? compliance? onboarding?
Who reads the report — engineers? CTO? legal? buyer?
Time budget — 4 hours? 4 days? 4 weeks? This determines depth.
What's in scope — which repos / services / domains / accounts. Get it confirmed in writing.
What's explicitly out of scope — third-party SaaS, customer data, anything the client did not authorize. Get this confirmed too.
Entry points — what URLs / endpoints does this expose? Background workers? CLIs?
Auth story — how do users log in, what session mechanism, are admins separate?
Data — what's stored, where (Postgres, Mongo, S3, files on disk, third parties)?
Secrets — where are they (env, vault, hardcoded — yes, look)?
Deploy — how does code get to production? Who can deploy? CI/CD or manual?
Blast radius — if this whole system were compromised tomorrow, what's the worst that happens? Customer data leak? Money lost? Operations halted? Reputation only?
If you cannot answer one of these from a 30-minute look, that's already a finding.
Step 2 — Inventory the surface
Now enumerate everything that matters.
Repositories and branches
git log --oneline | head -20
git log --all --format='%aN' | sort -u # who has committed
git tag # release cadence
git remote -v # where is it publishedls -la .github/ # workflows, codeowners
Run automated tools early, parse their output later. The tools give you a haystack of candidates; the manual review (Step 4–6) figures out which are real.
Enable in repo Settings → Code security → CodeQL analysis. It's free for public repos and worth its quotas for private. The results land in the Security tab; treat them as candidates, not verdicts.
Issues outside its rule set, recent CVEs not yet ruled
No tool finds broken access control. That is the single most common high-severity finding in real audits, and it requires manual review. Plan time accordingly.
Step 4 — Manual review — Auth surface
Auth surface is where the highest-impact findings cluster. Walk every entry point and answer:
Is auth checked? Server-side, in the handler itself — not just at middleware.
Is authorization checked? Auth says "you are X"; authz says "X may do this." They are not the same check.
Are object IDs resolved against the requester?GET /invoices/:id must verify the invoice belongs to the requesting user.
What happens on auth failure? Generic error (good) or detailed enumeration ("user not found" vs "wrong password" — bad)?
Where are session cookies issued?HttpOnly, Secure, SameSite=Lax?
Password reset and email change flows? Single-use token, expiring, invalidates sessions on success?
# Find every route + look for the auth check
grep -rEn "app\.(get|post|put|delete|patch)\(['\"]" src | head -40
# Then for each, check the handler for: session lookup, role check, owner check
The report exists to drive action. Optimize for "can a different engineer fix this in a sprint?"
Per finding
## [CRITICAL] Broken access control on /api/invoices/:id
### Summary
Any authenticated user can read any invoice by ID. No owner check.
### Evidence
- File: src/api/invoices/[id]/route.ts:12
- Reproduction: as user A, fetch /api/invoices/<an id belonging to user B>
$ curl -H "Cookie: $A_SESSION" https://app.example.com/api/invoices/$B_INVOICE_ID
→ 200 OK with B's data
### Impact
Cross-tenant data exposure. Any logged-in user reads every invoice.
### Remediation
Add owner check in the handler:
const invoice = await db.invoices.findFirst({ where: { id, userId: session.userId }});
if (!invoice) return NextResponse.json({ error: 'not found' }, { status: 404 });
### Severity reasoning
CRITICAL — affects all customer data, exploitable by any logged-in user, no
detection in current monitoring.
### Suggested owner: <name>
### Suggested deadline: <date — typically 7 days for critical>
Severity classes
Use a small scale, consistently applied:
CRITICAL — exploitable without auth, or with low-effort auth, affects all users or money / data integrity
HIGH — exploitable with some pre-condition (specific user role, specific data), affects sensitive data
MEDIUM — exploitable but limited blast radius, or requires significant attacker effort
LOW — defense-in-depth, hygiene improvement, not directly exploitable
INFO — observation, no action required
Aggressive severity inflation kills the report's usefulness. If everything is HIGH, nothing is HIGH.
Group by severity, then by area
A reader skims for CRITICALs and HIGHs first. Make that easy. Within severity, group by area (auth, data handling, infra) so an owner can take their slice.
Include a one-page summary
Decision-makers read the summary, not the report. Cover:
How many findings, by severity
The top 3 to fix this week
The systemic patterns (e.g. "auth checks are inconsistent across handlers — not a finding-per-handler problem")
Suggested timeline / sprint allocation
Step 10 — Anti-patterns junior auditors fall into
Boil the ocean — trying to audit everything in scope to the same depth. Time-box per area; go deep where impact is highest.
Tool output is the report — pasting npm audit output without synthesis or prioritization. Tool output is candidates, not findings.
No reproduction steps — "I think this might be vulnerable" is not a finding. Either prove it or downgrade to INFO.
Severity inflation — calling everything CRITICAL because the auditor wants attention. Kills credibility.
Wrong audience — writing for engineers when the buyer is the CTO, or vice versa. Match the language.
No remediation — listing problems without "do this to fix" leaves the recipient stuck.
Adversarial tone — "the developers clearly did not understand security" is unproductive. Frame as observations + fixes.
Missing the systemic — listing 30 instances of the same pattern, instead of "this pattern occurs throughout the codebase; fix here is to introduce a shared helper / linter rule."
Auditing without authorization — never audit a system you do not have written permission for, even if you think you're being helpful.
Step 11 — After delivery
Walk through the report with the team if possible. A 30-minute call beats a 50-page document for getting buy-in.
Offer to retest specific findings after fixes — closes the loop.
Document what's been fixed in the report itself, or in a follow-up appendix.
Note what's deferred with the reasoning. "Accepted risk: X, until Y date, owner Z" is fine; "ignored" is not.
When you find a critical mid-audit
Stop. Notify the client / stakeholder same-day if the finding affects customer data, money, or trust. Holding a CRITICAL for a final report on Friday when you found it on Monday is itself a finding.