Web Application Hardening Checklist (Practical Guide)
A web application hardening checklist is a repeatable set of security controls and configuration checks used to reduce attack surface and prevent common web-app compromises. It focuses on secure defaults across the application code, framework settings, server/runtime, and deployment pipeline.
A web application hardening checklist is a repeatable set of controls that reduces attack surface and prevents common compromises caused by weak authentication, broken authorization, insecure defaults, and configuration drift. Use this hardening checklist at release time, after significant changes, and as a quarterly “drift” review—especially for internet-facing apps that handle credentials, PII, or admin functions.
How it works
Hardening works by systematically addressing the most frequent failure modes in web apps—weak authentication, broken authorization, insecure configuration, injection, sensitive data exposure, and poor observability—using a standard, pre-release and continuous verification process.
Use the checklist in three passes:
- Design/Build pass (shift-left): confirm the app’s security requirements and safe patterns (authZ model, input validation strategy, secrets handling).
- Release pass (go-live gate): validate configuration and runtime settings (TLS, headers, cookies, CORS, debug flags, access to admin endpoints).
- Continuous pass (operations): monitor logs, rotate secrets, patch dependencies, and re-run tests after deployments and infrastructure changes.
If you need a companion control set for images and registries, see our container image security checklist: container image security checklist.
Practitioner checklist (what to do next)
1) Authentication & account security
- Require MFA for admin and privileged users; strongly prefer phishing-resistant methods for high-risk apps.
- Enforce secure password policy (length-based, block known-breached passwords, rate-limit attempts).
- Implement account lockout or progressive throttling (avoid easy DoS).
- Secure password reset flows:
- Single-use, short-lived tokens
- Token stored hashed server-side
- Don’t leak whether a user exists
If your team needs a clear baseline for password requirements, start here: how do i create a strong password.
Practical tooling tip (optional, but effective): using a business-grade password manager helps reduce shared secrets and weak credential habits. 1Password is a common choice for teams: Try 1Password →.
2) Session management
- Set cookies correctly:
HttpOnly,Secure,SameSite=Lax(orStrictwhere possible)- Short session lifetime for sensitive apps; rotate session IDs after login/privilege change
- Store sessions server-side for high-risk apps; if using JWTs, limit scope/lifetime and plan revocation.
3) Authorization (the “hardest” part that breaks most)
- Enforce authorization server-side on every request; don’t trust client-side claims.
- Default-deny access control; build a consistent policy layer (RBAC/ABAC).
- Add object-level checks (IDOR prevention): verify the requesting user can access that specific record.
4) Input handling & output encoding
- Validate inputs by allowlist (type, length, format) at boundaries.
- Use parameterized queries/ORM to prevent SQL injection.
- Encode output for the correct context (HTML, attribute, JS, URL) to prevent XSS.
- Disable dangerous parsers/features unless required (e.g., XML external entities).
5) Security headers & browser controls
- Enable core security headers (tune to your app):
Content-Security-Policy(CSP) to reduce XSS impactX-Content-Type-Options: nosniffReferrer-PolicyPermissions-PolicyStrict-Transport-Security(HSTS) once HTTPS is stable- Ensure you are not exposing sensitive data in client-side storage (localStorage/sessionStorage).
6) TLS and transport security
- Redirect HTTP → HTTPS; remove mixed content.
- Use modern TLS settings; disable obsolete protocols/ciphers.
- Consider mTLS for internal service-to-service traffic where appropriate.
- Pinning is generally operationally risky; prefer robust PKI and monitoring.
7) CORS, CSRF, and request integrity
- Keep CORS tight: explicit allowed origins; avoid
*with credentials. - Use CSRF protection for cookie-based sessions (tokens, SameSite cookies, double-submit where appropriate).
- Validate
Origin/Refererfor high-risk state-changing actions as defense-in-depth.
8) File upload & content handling
- Restrict allowed file types; validate by content sniffing (magic bytes), not only extension.
- Store uploads outside the web root; serve via controlled handler.
- Scan uploads (malware) if your risk profile requires it.
- Set size limits and timeouts to prevent resource exhaustion.
Practical tooling tip (when you accept uploads): if you need endpoint and malware scanning on developer workstations (and sometimes on servers, depending on policy), Malwarebytes is a common option: Get Malwarebytes →.
9) Secrets, configuration, and environment hygiene
- Remove debug modes, verbose errors, and dev tools from production.
- No secrets in source control; use a secrets manager or secure environment injection.
- Rotate credentials periodically and on incident; scope secrets to least privilege.
- Separate environments (dev/stage/prod) with distinct keys and access policies.
10) Dependencies & supply chain
- Maintain an SBOM (even lightweight) and monitor for vulnerable packages.
- Lock dependencies; review high-risk updates.
- Remove unused libraries/features to reduce attack surface.
- Validate build provenance where possible (signed artifacts, CI controls).
11) Logging, monitoring, and alerting
- Log security-relevant events:
- logins, failures, password resets, privilege changes
- admin actions, access denials, suspicious input patterns
- Avoid logging secrets (tokens, passwords, full payment data).
- Centralize logs; create alerts for brute force, unusual 4xx/5xx spikes, and privilege escalation indicators.
12) Runtime, server, and network posture
- Minimize exposed endpoints; restrict admin interfaces by network and authentication.
- Run with least privilege (non-root containers/users).
- Set resource limits; enable WAF/rate limiting for internet-facing apps.
- Patch OS, container base images, and web server regularly.
Technical notes: ready-to-run checks and config snippets
Verify secure response headers
Use curl to quickly inspect headers:
curl -I https://example.com
Look for (example baseline):
Strict-Transport-Security: max-age=31536000; includeSubDomainsContent-Security-Policy: ...X-Content-Type-Options: nosniffReferrer-Policy: strict-origin-when-cross-originPermissions-Policy: ...
Example: Nginx header hardening (adjust CSP carefully)
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# Enable HSTS only after confirming HTTPS everywhere
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# CSP needs app-specific tuning; start in Report-Only mode if unsure
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'" always;
Example: Cookie flags (typical framework target)
When setting session cookies, aim for:
Set-Cookie: session=...; Path=/; Secure; HttpOnly; SameSite=Lax
For apps embedded in third-party contexts you may need SameSite=None; Secure and compensating CSRF controls.
Check TLS posture from the outside
# Basic certificate and handshake info
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
For deeper scanning, use your organization’s approved TLS scanner/tooling and ensure results are tracked as configuration debt.
Log patterns worth alerting on
Examples to watch for in web/app logs:
- Repeated 401/403 from same IP or user (credential stuffing, brute force)
- Spikes in 400/422 (input probing), 404 (endpoint discovery), 500 (crash probing)
- Requests containing: "' OR 1=1", "<script", "UNION SELECT", "../", "%2e%2e%2f"
- Unexpected admin endpoint hits: /admin, /manage, /debug, /metrics
Use rate-based detection plus context (user agent, geolocation, known bad IPs) to reduce noise.
When you’ll encounter it
You’ll use a web application hardening checklist whenever a web app is:
- Internet-facing (public marketing sites with forms, customer portals, SaaS dashboards, APIs).
- Handling credentials, PII, or payments, where compliance and breach impact are high.
- Undergoing change: new releases, framework upgrades, infrastructure migrations, new authentication provider, or new admin features.
- Experiencing suspicious activity: brute force attempts, unexpected spikes in errors, defacement attempts, data access anomalies.
- Going through audits: security reviews, customer questionnaires, or baseline alignment (e.g., OWASP ASVS-inspired controls).
Operationally, the best time to apply it is: - Before go-live, as a release gate - After each significant deployment - After incident response, to prevent recurrence - Quarterly, as a “configuration drift” check
Related terms
A widely used awareness list of common web application risk categories (useful for prioritization).
A more testable application security verification standard; good for turning “checklists” into measurable requirements.
Integrating security into requirements, design, coding, testing, and operations.
A browser-enforced policy that restricts what content can load/execute, reducing XSS impact.
Forces browsers to use HTTPS for a domain once enabled.
Attacks that trick a user’s browser into making unintended authenticated requests.
Broken authorization where users can access other users’ objects by changing IDs.
A control that filters/blocks malicious HTTP requests; best as defense-in-depth, not a replacement for fixing app flaws.
Practices/tools for storing and rotating credentials and keys securely.
An inventory of software components to help track and respond to vulnerable dependencies.