This is the final article in the Security for Developers series. It brings everything together into a single, actionable checklist you can use for every project. Bookmark this page and review it whenever you start a new project or prepare for a security review.
How to Use This Checklist
Each item is marked with a priority level:
- P0 (Critical): Do this before going to production. Skipping it means you are vulnerable.
- P1 (High): Do this within the first week of production. Important for security posture.
- P2 (Medium): Do this within the first month. Improves defense in depth.
- P3 (Low): Nice to have. Do when you have time.
Authentication Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Hash passwords with bcrypt or Argon2 | P0 | Never store plaintext. Use cost factor 12+ for bcrypt. |
| 2 | Enforce minimum password length of 8 characters | P0 | NIST recommends 8+ characters. Do not require special characters. |
| 3 | Use HTTPS for all authentication endpoints | P0 | Credentials in transit must be encrypted. |
| 4 | Implement account lockout after failed attempts | P1 | Lock after 5-10 failed attempts for 15-30 minutes. |
| 5 | Use JWT with short expiration (15-60 min) | P1 | Combine with refresh tokens for longer sessions. |
| 6 | Sign JWTs with RS256 or EdDSA (not HS256 for distributed) | P1 | Asymmetric signing prevents key sharing. |
| 7 | Store tokens in httpOnly cookies (not localStorage) | P1 | Prevents XSS from stealing tokens. |
| 8 | Implement refresh token rotation | P1 | Invalidate old refresh token on each use. |
| 9 | Validate JWT signature and expiration on every request | P0 | Never trust a token without validation. |
| 10 | Support multi-factor authentication (MFA) | P2 | TOTP or WebAuthn. SMS is better than nothing. |
| 11 | Check passwords against breached lists (Have I Been Pwned) | P2 | Reject passwords that appear in known breaches. |
| 12 | Log all authentication events | P1 | Successful and failed logins, password changes. |
Reference: Tutorial #2: Authentication
Authorization Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Check authorization on every request (server-side) | P0 | Never trust the client. |
| 2 | Deny by default | P0 | Whitelist allowed actions. Everything else is denied. |
| 3 | Use role-based access control (RBAC) | P1 | Define roles (admin, editor, viewer) with specific permissions. |
| 4 | Validate ownership for resource access | P0 | User A cannot access User B’s data (prevent IDOR). |
| 5 | Use UUIDs instead of sequential IDs in URLs | P1 | /api/users/a1b2c3d4 instead of /api/users/123. |
| 6 | Implement OAuth 2.0 with PKCE for third-party auth | P1 | Required for mobile and SPA applications. |
| 7 | Validate OAuth state parameter | P0 | Prevents CSRF in OAuth flows. |
| 8 | Log all authorization denials | P1 | Detect privilege escalation attempts. |
Reference: Tutorial #3: Authorization
Injection Prevention Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Use parameterized queries for all SQL | P0 | Never concatenate user input into SQL. |
| 2 | Use an ORM with parameterized queries | P1 | GORM, SQLAlchemy, Room, Prisma all use parameters by default. |
| 3 | Validate and sanitize all user input | P0 | Whitelist approach: only allow expected characters. |
| 4 | Escape output in HTML templates | P0 | Use auto-escaping template engines (Go html/template, React JSX). |
| 5 | Set Content-Security-Policy header | P1 | Prevents inline scripts and unauthorized resources. |
| 6 | Use HttpOnly flag on session cookies | P0 | Prevents JavaScript from accessing cookies. |
| 7 | Sanitize HTML if you must accept it | P1 | Use DOMPurify or a server-side equivalent. |
Reference: Tutorial #4: Injection Prevention
HTTPS and Transport Security Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Use HTTPS everywhere | P0 | All pages, all APIs, all environments. |
| 2 | Use TLS 1.2 as minimum, prefer TLS 1.3 | P0 | Disable TLS 1.0 and 1.1. |
| 3 | Use Let’s Encrypt for certificates | P1 | Free, automated, trusted by all browsers. |
| 4 | Enable HSTS header | P1 | Strict-Transport-Security: max-age=31536000; includeSubDomains. |
| 5 | Redirect HTTP to HTTPS | P0 | All HTTP requests should redirect to HTTPS. |
| 6 | Use strong cipher suites | P1 | Test with SSL Labs (target A+ rating). |
| 7 | Enable certificate pinning for mobile apps | P2 | Prevents MITM attacks on mobile. |
Reference: Tutorial #5: HTTPS and TLS
CSRF and CORS Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Use SameSite=Lax or Strict on all cookies | P0 | Prevents most CSRF attacks. |
| 2 | Implement CSRF tokens for state-changing requests | P1 | Synchronizer token pattern or double-submit cookie. |
| 3 | Set CORS headers restrictively | P1 | Never use Access-Control-Allow-Origin: * with credentials. |
| 4 | Validate the Origin header | P1 | Reject requests from unexpected origins. |
| 5 | Use custom headers for API requests | P2 | Custom headers trigger CORS preflight, adding a layer of protection. |
Reference: Tutorial #6: CSRF, Tutorial #7: CORS
API Security Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Implement rate limiting | P0 | Per-user and per-IP. Start with 100 requests/min. |
| 2 | Validate all input (type, length, format) | P0 | Reject unexpected input early. |
| 3 | Return minimal data in responses | P1 | Never expose internal IDs, stack traces, or debug info. |
| 4 | Set request size limits | P1 | Prevent resource exhaustion from large payloads. |
| 5 | Use API keys or OAuth tokens for authentication | P0 | Never rely on IP-based authentication. |
| 6 | Version your API | P2 | Deprecate old versions with a security timeline. |
| 7 | Log all API access | P1 | Track who accessed what, when, and from where. |
Reference: Tutorial #8: API Security
Secrets Management Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Never hardcode secrets in source code | P0 | Use environment variables at minimum. |
| 2 | Add .env to .gitignore | P0 | Before your first commit. |
| 3 | Use CI/CD secrets for pipelines | P0 | GitHub Actions secrets, GitLab variables. |
| 4 | Install pre-commit hooks (gitleaks, detect-secrets) | P1 | Catch secrets before they are committed. |
| 5 | Use a secret manager in production | P1 | HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager. |
| 6 | Rotate secrets on a schedule | P1 | 90 days for passwords and API keys. |
| 7 | Never log secrets | P0 | Mask in logs and error messages. |
| 8 | Commit .env.example with placeholder values | P2 | Helps other developers set up the project. |
Reference: Tutorial #9: Secrets Management
Security Headers Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Content-Security-Policy | P1 | Prevent XSS, clickjacking, and unauthorized resources. |
| 2 | Strict-Transport-Security | P1 | Force HTTPS for 1 year. |
| 3 | X-Content-Type-Options: nosniff | P1 | Prevent MIME-type sniffing. |
| 4 | X-Frame-Options: DENY | P1 | Prevent clickjacking. |
| 5 | Referrer-Policy: strict-origin-when-cross-origin | P2 | Control referrer information. |
| 6 | Permissions-Policy | P2 | Disable camera, microphone, geolocation if not needed. |
Reference: Tutorial #10: Security Headers
Dependency and Supply Chain Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Use lockfiles for all package managers | P0 | go.sum, package-lock.json, requirements.txt. |
| 2 | Run vulnerability scans in CI/CD | P0 | npm audit, govulncheck, pip-audit, Trivy. |
| 3 | Enable Dependabot or Renovate | P1 | Automated dependency updates. |
| 4 | Pin exact dependency versions | P1 | No version ranges in production. |
| 5 | Review new dependencies before adding | P2 | Check maintenance status, license, and vulnerability history. |
| 6 | Generate SBOMs for releases | P3 | Becoming required by regulation. |
Reference: Tutorial #11: Dependency Scanning
Logging and Monitoring Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Log all authentication events | P0 | Successes, failures, lockouts. |
| 2 | Log all authorization denials | P1 | Detect privilege escalation. |
| 3 | Never log sensitive data | P0 | Mask passwords, tokens, PII. |
| 4 | Use structured logging (JSON) | P1 | Easier to search and analyze. |
| 5 | Centralize logs | P1 | ELK, Loki+Grafana, or cloud logging. |
| 6 | Set up alerts for brute force and anomalies | P1 | 10+ failed logins in 5 min from same IP. |
| 7 | Define log retention policy | P2 | 90 days hot, 1 year cold storage. |
Reference: Tutorial #12: Logging and Monitoring
Container and Docker Checklist
| # | Item | Priority | Details |
|---|---|---|---|
| 1 | Run containers as non-root | P0 | USER directive in Dockerfile. |
| 2 | Use minimal base images | P1 | Alpine, distroless, or scratch. |
| 3 | Scan images for vulnerabilities | P0 | Trivy or Docker Scout in CI/CD. |
| 4 | Never put secrets in Dockerfiles | P0 | Use mounted files or Docker secrets. |
| 5 | Drop all capabilities, add only needed | P1 | cap_drop: ALL in docker-compose. |
| 6 | Use multi-stage builds | P1 | Smaller images, no build tools in production. |
| 7 | Pin base image versions | P1 | Never use :latest in production. |
| 8 | Set resource limits (CPU, memory) | P2 | Prevent resource exhaustion. |
| 9 | Do not expose unnecessary ports | P1 | Only expose what clients need. |
Reference: Tutorial #13: Container Security
Pre-Launch Security Review
Before going to production, walk through this abbreviated checklist:
Must-Have (P0)
- HTTPS enabled with valid certificate
- Passwords hashed with bcrypt or Argon2
- Parameterized queries for all database access
- Input validation on all user-facing endpoints
- Authorization checked on every request (server-side)
- Secrets not in source code or Docker images
- .env in .gitignore
- Rate limiting on authentication and API endpoints
- JWT validation on every request
- Containers running as non-root
- No sensitive data in logs
- Dependency vulnerability scan passing
Should-Have (P1)
- Security headers configured (CSP, HSTS, X-Frame-Options)
- CSRF protection for state-changing requests
- CORS configured restrictively
- Structured logging with centralized collection
- Alerting for brute force and suspicious activity
- Dependabot or Renovate enabled
- Pre-commit hooks for secret detection
- Docker images scanned and using minimal base
Nice-to-Have (P2+)
- MFA support
- Certificate pinning for mobile apps
- SBOM generation
- Audit trail for admin actions
- Log retention policy documented
Security is a Journey
Security is not a one-time task. It is an ongoing process:
- Review this checklist at the start of every project
- Run dependency scans weekly (automate with Dependabot)
- Review logs and alerts weekly
- Update dependencies monthly
- Rotate secrets quarterly
- Conduct a security review annually (or when the architecture changes)
Series Complete
You have completed the entire Security for Developers series. You now have the knowledge to write secure code, prevent the most common attacks, and protect your users. Remember: most security breaches happen because developers skip the basics. Do not skip the basics.
Full series: Security for Developers
Related Articles
- Security for Developers #1: Web Security Basics — OWASP Top 10
- Security for Developers #2: Authentication
- Security for Developers #4: Injection Prevention
- Security for Developers #8: API Security
- Security for Developers #9: Secrets Management
- Security for Developers #11: Dependency Scanning
- Security for Developers #13: Container Security