Code audit: [Project name]
Replace everything in [brackets]. Tick a line only when you have seen the evidence yourself. Anything that fails becomes a numbered finding in the log at the end, and the audit passes only when the log has no open critical or high findings and the product is live.
01Scope
Pin exactly what is being audited. An audit of "the app" at no particular commit cannot be repeated.
- Repository: [URL]
- Commit or tag: [SHA or release tag]
- Agreed scope: [PRD version or baseline number audited against]
- Environment: [Production URL, store build, or staging]
- Auditor and date: [Name], [date]
02Requirements coverage
Does the build match what was agreed? Work through the requirements one by one against the frozen scope.
- Every Must requirement has acceptance criteria
- Every Must requirement has finished work pointing at it
- Each acceptance check passes on the running product
- Requirements changed after sign-off are flagged, with old and new wording
- Requirements dropped after sign-off are recorded as decisions, not deleted
- Commits and pull requests reference requirement keys
03Access control
Most serious findings in small products live here. Test by changing IDs and removing sessions, not by reading the UI.
- Every route that reads or writes private data checks the session
- Admin actions check a role or permission, not only that someone is signed in
- Changing an ID in a URL or request cannot reach another account's data
- API tokens are scoped, and revoking one takes effect immediately
- Password reset, invite and magic links expire and work only once
04Secrets and configuration
Check the history as well as the current tree. A key deleted in a later commit is still published.
- No keys, tokens or passwords in the repository or its history
- Environment files are ignored by version control
- No server secret is exposed to the browser bundle through a public variable
- Production and development use different credentials
- Leaked or shared credentials have been rotated
05Dependencies
Use an advisory database such as npm audit or OSV and record the advisory IDs. Do not rely on memory.
- Known advisories checked, with IDs recorded for anything found
- Lockfile committed and used in the build
- Unmaintained or abandoned packages noted
- Install scripts from new dependencies reviewed
06Input handling
Anything a user can send is untrusted, including headers, file names and webhook bodies.
- Database queries are parameterised, never built from strings
- No eval or dynamic code execution on user input
- User content is escaped before rendering
- Uploads are checked for type and size, and stored outside the web root
- Server-side fetches of user-supplied URLs are restricted
- Public forms have rate limits or abuse protection
07Money paths
Rank anything here above everything else. A bug that charges twice or credits twice costs money every hour it is live.
- Payment and order handlers are idempotent: a retry does not charge twice
- Webhook signatures are verified before anything is trusted
- Prices and amounts are computed on the server, never taken from the client
- Refunds, credits and vouchers cannot be spent twice under concurrent requests
08Reliability and operations
What happens on a bad day, and whether anyone would know.
- Errors are reported to monitoring that someone reads
- Backups exist, and a restore has actually been tried
- Database migrations are applied before the code that depends on them ships
- Scheduled jobs are safe to run twice
09It is live
An audit of something nobody outside the team can reach has not finished.
- Deployed and reachable by someone who does not work here
- Production URL or store listing recorded
- Sign-up and the core flow work in production, not only locally
10Findings log
One row per failed check. Rank by what costs money or exposes data first. A finding without evidence is an opinion; leave it out or go and get the evidence.
Severity: Critical, High, Medium, Low or Info
| ID | Severity | Where | Evidence | Reproduce | Suggested fix | Status |
|---|---|---|---|---|---|---|
| F-001 | [Critical] | [path/file.ts:42] | [What shows the problem] | [Steps] | [Change to make] | Open |
| F-002 | [High] | [Route or file] | [What shows the problem] | [Steps] | [Change to make] | Open |
11Verdict
Pass, or another iteration. There is no partial pass.
- Result: [Pass / Another iteration]
- Open findings: [Count by severity]
- Follow-up work: [Where the fixes are tracked]
- Next audit: [Date or trigger]