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-Securityheader presentX-Content-Type-Options: nosniffpresent- No
X-Powered-Byor 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.