Why a Security Audit Checklist Matters
You can't fix what you don't measure. This checklist covers 50 concrete security checks every startup should run before launching, before fundraising, and before signing the first enterprise customer. It's distilled from auditing 30+ startup codebases at SableOffensive.
Print it. Run through it before each release. If you can't check 80%+ green, you're not ready.
Section 1: Authentication (8 checks)
- Password requirements: Minimum 10 characters, blocks the top 10,000 leaked passwords (use HaveIBeenPwned).
- Email confirmation: Required before account is fully active.
- Password reset tokens: Single-use, expire in 30 minutes or less.
- Account lockout: Lock after 5 failed login attempts for at least 15 minutes.
- MFA available: Offered to all users, required for admin accounts.
- Session expiration: Sessions expire after inactivity (max 30 days for "remember me").
- Logout invalidates server-side: Not just clearing the cookie — token must be invalidated server-side.
- OAuth state parameter: CSRF protection on OAuth flows (Google, GitHub, etc.).
Section 2: Authorization & Access Control (7 checks)
- Every API route has explicit auth check: No route reachable without authentication unless explicitly public.
- Object-level authorization (BOLA/IDOR): Every resource access verifies ownership — not just "user is logged in".
- Role-based access enforced server-side: Admin actions check role on the server, not just hide UI elements.
- Sequential IDs avoided for sensitive resources: Use UUIDs to prevent enumeration.
- Direct object references validated: URL params like
?userId=123always cross-checked with session. - Default deny: Permissions default to "deny" — explicit allowlist for every action.
- Admin endpoints separated:
/adminroutes restricted by IP, MFA, or both.
Section 3: Secrets Management (6 checks)
- No secrets in client bundle: Run
grep -r "sk_\|api_key\|service_role" .next/static/after build — should return nothing. - No secrets in git history: Run
trufflehog git file://. --since-commit HEAD~100— clean history. - .env files in .gitignore: Verify
.env,.env.local,.env.productionall gitignored. - Secrets rotated quarterly: JWT signing keys, API keys, database passwords on rotation schedule.
- Production vs staging credentials separated: Different keys, different databases.
- Secret manager used (not env vars in production): Vault, AWS Secrets Manager, Doppler — not just plain env vars.
Section 4: Input Validation (5 checks)
- All user input validated with schema: Zod, Yup, or similar — every API request body, query param, and header.
- SQL injection: parameterized queries only: No string concatenation in queries. Audit all uses of
$queryRawUnsafeor equivalent. - XSS: output encoding by default: Frameworks (React, Vue) escape by default — but
dangerouslySetInnerHTMLuses are reviewed. - Command injection: no
exec()with user input: Audit all uses ofchild_process.exec,eval, dynamic imports. - SSRF protection: Routes that fetch URLs validate against an allowlist + block internal IPs.
Section 5: Security Headers (8 checks)
Test all of these with our free security headers checker.
- Strict-Transport-Security:
max-age=63072000; includeSubDomains; preload - Content-Security-Policy: Strict policy blocking inline scripts where possible.
- X-Content-Type-Options:
nosniff - X-Frame-Options:
DENY(orSAMEORIGINif you embed your own iframes). - Referrer-Policy:
strict-origin-when-cross-origin - Permissions-Policy: Disable camera, microphone, geolocation unless needed.
- Cross-Origin-Opener-Policy:
same-origin(prevents tab-based attacks). - HTTPS enforced everywhere: No HTTP fallback, no mixed content warnings.
Section 6: API Security (5 checks)
- Rate limiting on all endpoints: Especially auth (login, signup, password reset). Tune by endpoint risk.
- CORS configured restrictively: Specific origin allowlist, never
*with credentials. - API versioning:
/api/v1/structure to support deprecation without breaking customers. - Pagination limits enforced: Max page size capped server-side (e.g., max 100 items per request).
- Mass assignment protection: No
{...body}spread into database calls — explicit field allowlist.
Section 7: Dependencies (3 checks)
- npm audit clean: No critical or high-severity vulnerabilities. Run weekly.
- Lockfile committed:
package-lock.json,yarn.lock, orpnpm-lock.yamlin git. - Dependabot or Renovate enabled: Automatic PRs for dependency updates.
Section 8: Infrastructure (5 checks)
- No public S3 buckets / Storage buckets: Audit Supabase Storage policies, AWS S3 ACLs.
- Database not exposed to internet: Postgres on private network, accessible only from app servers.
- SSH keys instead of passwords: Servers reject password-based SSH.
- Firewall rules minimal: Only required ports open. Default deny.
- Backups exist and tested: Daily backups + tested restore procedure (untested = doesn't work).
Section 9: Logging & Monitoring (3 checks)
- Auth events logged: Logins, logouts, password resets, failed attempts — all logged with IP and user agent.
- Sensitive data not logged: Passwords, tokens, full credit card numbers — never in logs.
- Alerting configured: 5+ failed logins, unusual admin activity, large data exports — trigger alerts.
How to Score Yourself
| Score | Status | Action |
|---|---|---|
| 40-50 / 50 | Production-ready | Schedule a pentest to validate |
| 30-39 / 50 | Needs work | Fix Critical/High items first |
| 20-29 / 50 | High risk | Pause feature work — fix security |
| 0-19 / 50 | Critical exposure | Take service offline until fixed |
Compliance Mapping
If you're pursuing compliance, this checklist maps to:
| Framework | Sections Covered |
|---|---|
| SOC 2 Type II (CC6, CC7) | All sections |
| ISO 27001 (A.9, A.13, A.14) | Auth, API, Infrastructure, Logging |
| GDPR (Article 32) | Auth, Secrets, Headers, Logging |
| HIPAA (164.312) | Auth, Authorization, Logging, Infrastructure |
| PCI DSS (Requirement 6, 8) | Auth, Input Validation, Headers, Dependencies |
What This Checklist Doesn't Cover
This is a pre-pentest baseline — not a substitute for one. Manual pentesting finds:
- Business logic flaws: Pricing manipulation, workflow bypasses, race conditions in financial transactions.
- Chained vulnerabilities: Three Medium findings combined into a Critical exploit.
- Authorization at scale: Edge cases where one user can affect another.
- Cryptographic flaws: Weak random number generation, predictable tokens, custom crypto.
- Architecture-level issues: Trust boundaries crossed, services that shouldn't talk to each other.
Free Tools to Run Through the Checklist
- Headers (Section 5): SableOffensive Free Scan or securityheaders.com
- Dependencies (Section 7):
npm audit,snyk test,trivy fs - Secrets (Section 3):
trufflehog,gitleaks - SAST (Section 4): Semgrep, CodeQL
- Cloud config (Section 8): Prowler (AWS), ScoutSuite (multi-cloud)
Validate Your Score With a Real Pentest
This checklist is the floor — not the ceiling. To know your true security posture, you need an external test.
SableOffensive offers tiered pentesting designed for the startup budget:
- Free Scan — security headers + basic checks (sections 5, 8). Free.
- Pre-Launch Check ($29) — automated coverage of OWASP Top 10 + headers + secrets. 24-48h delivery.
- Founder Shield ($79) — manual review of auth, authorization, API security + executive report. 24-48h delivery.
- Scale Secure ($199) — full audit + code review + 30-day continuous monitoring. 24-48h delivery.
- Custom engagement — for compliance, multi-application, or complex stacks. Email [email protected] for quote.
50% money-back guarantee if we find zero issues. Reports include re-test of fixes for Critical/High findings.