How to Run Your Own OWASP Top 10 Security Audit: A Step-by-Step Checklist

A developer-focused walkthrough of the OWASP Top 10 web application security risks, with code examples showing vulnerable and fixed versions.

Turning a Reference List into an Actual Audit

Knowing the OWASP Top 10 categories is one thing; systematically checking your own application against them is another. This is a practical, repeatable audit process you can run before a release or on a recurring schedule.

Step 1: Automated Dependency and Static Analysis

# Node.js
npm audit --audit-level=high

# PHP
composer audit

# Python
pip-audit

Run these in CI on every PR, not just before releases — vulnerable dependencies get merged in silently otherwise.

Step 2: Access Control Spot-Checks

Pick five endpoints that return user-specific data and manually verify authorization, not just authentication:

# Log in as User A, grab their token
curl -H "Authorization: Bearer $USER_A_TOKEN" https://api.example.com/orders/123

# Try accessing the same resource with User B's token
curl -H "Authorization: Bearer $USER_B_TOKEN" https://api.example.com/orders/123
# Should return 403, not the order data

Step 3: Injection Surface Review

grep -rn "whereRaw\|query(\`" --include="*.php" --include="*.js" ./src

Grep your codebase for raw query patterns and manually verify each result uses parameter binding, not string concatenation.

Step 4: Automated Scanning with OWASP ZAP

docker run -t owasp/zap2docker-stable zap-baseline.py \
  -t https://staging.example.com -r zap-report.html

Run this against staging, never production, and review the report for flagged headers, cookie flags, and exposed endpoints.

Step 5: Authentication Flow Review

  • Confirm login and password-reset endpoints are rate-limited
  • Verify password reset tokens expire and are single-use
  • Check that session tokens are invalidated on logout, not just cleared client-side

Step 6: Configuration Review Checklist

curl -I https://example.com
  • Strict-Transport-Security header present
  • X-Content-Type-Options: nosniff present
  • No X-Powered-By or verbose server version headers leaking stack details
  • Error responses don’t include stack traces in production

Step 7: Logging and Alerting Verification

Trigger a deliberate failed-login burst against a staging environment and confirm it actually generates an alert. An audit process is only as good as the alerting it validates.

Building This Into Your Release Process

Turn steps 1–3 into required CI checks, and schedule steps 4–7 as a recurring pre-release or quarterly review, tracked in a shared checklist so the audit doesn’t quietly get skipped under deadline pressure.

Conclusion

A security audit is far more valuable as a repeatable process than a one-time review. Automate what you can in CI, and keep a lightweight manual checklist for the parts that still need human judgment.