Dev / IT15 min read

Web Application Security: The Complete Developer Checklist (2025)

A comprehensive security checklist covering authentication, authorization, input validation, cryptography, dependencies, infrastructure, and monitoring — everything a developer needs to ship secure software.

Security isn't a feature you add at the end — it's a discipline you build throughout development. This checklist covers every layer of a modern web application, organized so you can work through it systematically before shipping.

How to use this checklist: work through each section during development and before every major release. Items marked ⚠️ are critical — skip them only with documented justification.

1. Authentication

  • ⚠️ Passwords hashed with bcrypt (cost ≥ 12) or Argon2id — never MD5, SHA-1, or plain SHA-256
  • ⚠️ No plain-text passwords stored anywhere (logs, DB, emails)
  • ⚠️ Rate limiting on login endpoint (max 5 attempts per 15 min per IP)
  • Account lockout after repeated failures with notification to user
  • ⚠️ Multi-factor authentication available for sensitive accounts
  • "Forgot password" tokens are single-use, expire in ≤ 1 hour, hashed in DB
  • Username enumeration prevented (same response for invalid user vs wrong password)
  • Session invalidated on logout (server-side invalidation, not just deleting cookie)
  • Concurrent session limits enforced if required

2. Authorization

  • ⚠️ Every API endpoint explicitly checks authorization — no implicit trust
  • ⚠️ Resource-level access control: user can only access their own data
  • ⚠️ Admin functions require admin role check on the server (not just hidden in UI)
  • Principle of least privilege: services and users have minimum required permissions
  • JWT tokens validated on every request (signature + expiry + claims)
  • Sensitive operations (delete, transfer, admin actions) require re-authentication

3. Input Validation & Output Encoding

  • ⚠️ All user input validated on the server side (client-side validation is UX only)
  • ⚠️ Parameterized queries used for all database operations — no string concatenation
  • ⚠️ HTML output escaped before rendering user-controlled data
  • File uploads: validate type (not just extension), size limit, scan for malware
  • File uploads stored outside webroot or in cloud storage, not served directly
  • Redirects validate the destination URL against an allowlist
  • JSON input parsed with a size limit

4. Secrets & Configuration

  • ⚠️ No secrets in source code or git history
  • ⚠️ All secrets in environment variables or a secrets manager (Vault, AWS Secrets Manager)
  • .env files in .gitignore; .env.example committed instead
  • ⚠️ Production and development secrets are different values
  • API keys have minimal permissions (not root/admin keys)
  • Secrets rotated regularly and after team member offboarding
  • git log checked for accidental secret commits before first push

5. HTTPS & Transport Security

  • ⚠️ HTTPS enforced everywhere — HTTP redirects to HTTPS (301)
  • ⚠️ Valid certificate from trusted CA, not self-signed in production
  • TLS 1.2 minimum; TLS 1.3 preferred
  • HSTS header set with at least 1-year max-age
  • Cookies set with Secure, HttpOnly, SameSite attributes
  • Mixed content warnings resolved (no HTTP resources on HTTPS page)

6. HTTP Security Headers

# Minimum security headers
Content-Security-Policy: default-src 'self'
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
  • CSP defined and tested (no unsafe-inline for scripts without nonce)
  • Server version information hidden (server_tokens off in Nginx)
  • Error pages don't expose stack traces or framework information

7. Dependencies

  • ⚠️ npm audit / pip-audit run — no known high/critical vulnerabilities
  • Dependencies locked (package-lock.json, requirements.txt with pinned versions)
  • Automated dependency scanning in CI (Dependabot, Snyk, or similar)
  • Third-party scripts loaded from known CDNs with Subresource Integrity (SRI) hashes
  • No abandoned or unmaintained packages for security-critical functions

8. Session Management

  • Session tokens are cryptographically random and ≥ 128 bits
  • Session ID rotated on privilege escalation (login, role change)
  • Session timeout after inactivity (configurable, default ≤ 30 min for sensitive apps)
  • "Remember me" uses a separate long-lived token, not extending the session
  • CSRF protection on all state-changing requests (SameSite cookie or CSRF token)

9. Logging & Monitoring

  • Authentication events logged (success, failure, lockout)
  • ⚠️ Logs don't contain sensitive data (passwords, tokens, PII)
  • Authorization failures logged (403 responses)
  • Alerts configured for anomalies (high error rate, unusual traffic)
  • Log aggregation and retention policy defined
  • Uptime monitoring with alerting

10. Infrastructure

  • ⚠️ Firewall rules: only required ports open (typically 80, 443, and SSH from specific IPs)
  • SSH: key-only authentication, root login disabled
  • Automatic security updates enabled for OS
  • Database not publicly accessible (VPC/private network only)
  • Backups automated, tested, and stored separately
  • Principle of least privilege for cloud IAM roles

11. Before Each Release

  • git log reviewed for any debug code, test credentials, TODO security notes
  • New endpoints have authorization checks
  • Any new third-party integrations reviewed for data exposure
  • Sensitive changes reviewed by a second engineer
N

Nattapon Tonapan

Developer & creator of FreeUtil. Building free tools for developers and Thai users.

About the author →

RELATED ARTICLES

Dev / IT6 min read

What is JWT? Understanding JSON Web Tokens

Dev / IT5 min read

Base64 Encoding Explained: What It Is and When to Use It

Dev / IT8 min read

CIDR Notation and Subnetting: A Complete Guide

← Back to all articles