Use this as a practical security checklist before shipping to production.
- Transport & Network
- Authentication & Authorization
- Cookies & Storage
- Input Validation & XSS
- Content Security Policy (CSP)
- CSRF Protection
- Dependencies & Supply Chain
- Headers & Browser Security
- Client-Side Safety
- API Security
- Build & Deployment
- Frontend-Specific (React)
- Monitoring & Auditing
- Data Privacy & Compliance
- Common Security Mistakes
- Security Testing
- Golden Rules
- Quick Reference
- [ ] Enforce HTTPS everywhere
- [ ] Redirect HTTP β HTTPS
- [ ] Enable HSTS (HTTP Strict Transport Security)
- [ ] Use secure TLS config (TLS 1.2+)
- [ ] Disable mixed content
- [ ] Use a CDN with DDoS protection
- [ ] Configure proper TLS cipher suites
- [ ] Enable certificate pinning (mobile apps)
- [ ] Set long HSTS max-age (31536000 seconds minimum)
- [ ] Include subdomains in HSTS
- [ ] Preload HSTS when possible
- [ ] Disable insecure protocols (SSLv3, TLS 1.0, 1.1)
- [ ] Use strong Diffie-Hellman parameters
- [ ] Monitor certificate expiration
- [ ] Never store secrets in frontend
- [ ] Use short-lived access tokens (15-30 min)
- [ ] Use refresh tokens securely (HttpOnly cookies)
- [ ] Enforce server-side authorization
- [ ] Protect routes (not just UI)
- [ ] Logout clears all tokens
- [ ] Prevent token leakage via URLs
- [ ] Implement proper session timeout
- [ ] Use OAuth 2.0 / OIDC properly
- [ ] Implement MFA (Multi-Factor Authentication)
- [ ] Secure password reset flows
- [ ] Prevent account enumeration
- [ ] Implement rate limiting on auth endpoints
- [ ] Use PKCE for OAuth flows
- [ ] Validate JWT signatures server-side
- [ ] Check token expiration
- [ ] Implement proper token revocation
- [ ] Avoid storing passwords in plaintext
- [ ] Use strong password policies
- [ ] Implement brute-force protection
- [ ] Prefer HttpOnly cookies for auth tokens
- [ ] Use
Secureflag on cookies - [ ] Use
SameSite=LaxorStrict - [ ] Avoid storing tokens in
localStorage - [ ] Clear storage on logout
- [ ] Encrypt sensitive data (server-side)
- [ ] Set appropriate cookie expiration
- [ ] Use
__Host-or__Secure-cookie prefixes - [ ] Avoid storing PII in cookies
- [ ] Implement cookie consent (GDPR)
- [ ] Use sessionStorage for temporary data
- [ ] Clear sensitive data from memory
- [ ] Don't store secrets in IndexedDB
- [ ] Validate cookie domain and path
- [ ] Implement cookie rotation
- [ ] Validate inputs server-side
- [ ] Sanitize user-generated content
- [ ] Escape HTML output
- [ ] Avoid
dangerouslySetInnerHTML - [ ] Use trusted sanitizers (DOMPurify)
- [ ] Encode data before rendering
- [ ] Validate file uploads (type, size, content)
- [ ] Use parameterized queries (prevent SQL injection)
- [ ] Whitelist allowed characters
- [ ] Validate data types and formats
- [ ] Implement length limits
- [ ] Sanitize URLs before redirects
- [ ] Validate JSON schema
- [ ] Escape user content in attributes
- [ ] Use Content-Type validation
- [ ] Prevent HTML injection
- [ ] Validate email addresses properly
- [ ] Sanitize SVG uploads
- [ ] Use CSP to mitigate XSS
- [ ] Define strict CSP headers
- [ ] Disallow
unsafe-inline - [ ] Restrict script sources
- [ ] Restrict image/media domains
- [ ] Enable
object-src 'none' - [ ] Use nonce-based scripts
- [ ] Set
default-src 'none'as baseline - [ ] Use
script-src 'self'when possible - [ ] Implement CSP reporting
- [ ] Test CSP in report-only mode first
- [ ] Restrict
base-uri - [ ] Set
form-actiondirective - [ ] Use
upgrade-insecure-requests - [ ] Avoid wildcards in CSP
- [ ] Use hash-based CSP for inline scripts
- [ ] Implement frame-ancestors
- [ ] Monitor CSP violations
- [ ] Use CSRF tokens (synchronizer pattern)
- [ ] SameSite cookies enabled
- [ ] Protect state-changing requests
- [ ] Validate origin & referer headers
- [ ] Use double-submit cookie pattern
- [ ] Require custom headers for AJAX
- [ ] Validate CSRF tokens server-side
- [ ] Regenerate tokens per session
- [ ] Use anti-CSRF libraries
- [ ] Protect all POST/PUT/DELETE endpoints
- [ ] Don't use GET for state changes
- [ ] Implement origin validation
- [ ] Check Content-Type header
- [ ] Keep dependencies updated
- [ ] Run
npm audit/yarn auditregularly - [ ] Avoid unmaintained packages
- [ ] Lock dependency versions (package-lock.json)
- [ ] Verify third-party scripts
- [ ] Use Subresource Integrity (SRI)
- [ ] Review dependency licenses
- [ ] Use automated dependency updates (Dependabot)
- [ ] Scan for known vulnerabilities
- [ ] Minimize dependency count
- [ ] Audit transitive dependencies
- [ ] Use private npm registry
- [ ] Implement supply chain attack detection
- [ ] Verify package signatures
- [ ] Use npm/yarn workspaces safely
- [ ] Monitor for compromised packages
- [ ] Use reputable CDNs
- [ ] Set
X-Frame-Options: DENYor use CSPframe-ancestors - [ ] Set
X-Content-Type-Options: nosniff - [ ] Configure
Referrer-Policy: strict-origin-when-cross-origin - [ ] Set
Permissions-Policy(formerly Feature-Policy) - [ ] Disable server fingerprinting
- [ ] Set
X-XSS-Protection: 0(deprecated, use CSP) - [ ] Configure
Cross-Origin-Embedder-Policy(COEP) - [ ] Configure
Cross-Origin-Opener-Policy(COOP) - [ ] Configure
Cross-Origin-Resource-Policy(CORP) - [ ] Remove server version headers
- [ ] Set
Expect-CTheader - [ ] Configure proper CORS headers
- [ ] Avoid exposing stack traces
- [ ] Set secure cache headers
- [ ] Avoid exposing internal APIs
- [ ] Hide feature flags securely
- [ ] Rate-limit sensitive actions
- [ ] Prevent brute-force attacks
- [ ] Avoid detailed error messages
- [ ] Don't expose API keys in frontend
- [ ] Implement client-side rate limiting
- [ ] Validate user permissions client-side (UX only)
- [ ] Protect against clickjacking
- [ ] Prevent tabnabbing (
rel="noopener noreferrer") - [ ] Validate redirects
- [ ] Sanitize user-controlled URLs
- [ ] Implement CAPTCHA for sensitive forms
- [ ] Use secure random number generation
- [ ] Avoid exposing internal IDs
- [ ] Implement proper error handling
- [ ] Validate all API inputs
- [ ] Enforce auth on every request
- [ ] Use rate limiting (per IP, per user)
- [ ] Protect against mass assignment
- [ ] Implement request size limits
- [ ] Use API versioning
- [ ] Implement proper error handling
- [ ] Use HTTPS for all API calls
- [ ] Validate Content-Type headers
- [ ] Implement API key rotation
- [ ] Use JWT with short expiration
- [ ] Implement request signing
- [ ] Validate request methods
- [ ] Prevent parameter pollution
- [ ] Implement pagination limits
- [ ] Use GraphQL query depth limiting
- [ ] Implement field-level authorization
- [ ] Log API security events
- [ ] Implement API throttling
- [ ] Use API gateways
- [ ] Remove source maps from production
- [ ] Strip debug logs (
console.log,debugger) - [ ] Use environment variables for secrets
- [ ] Protect CI/CD secrets
- [ ] Enable monitoring & alerts
- [ ] Implement automated security scanning
- [ ] Use secure build environments
- [ ] Verify build artifacts
- [ ] Implement signed deployments
- [ ] Use separate environments (dev/staging/prod)
- [ ] Rotate deployment keys regularly
- [ ] Implement rollback procedures
- [ ] Use infrastructure as code
- [ ] Enable security headers via CDN/server
- [ ] Review deployment logs
- [ ] Implement blue-green deployments
- [ ] Use container scanning
- [ ] Never trust client-side checks
- [ ] Avoid storing secrets in JavaScript
- [ ] Secure redirects (validate URLs)
- [ ] Prevent open redirects
- [ ] Validate query params
- [ ] Avoid eval-like APIs (
eval,Function(),setTimeout(string)) - [ ] Use React's built-in XSS protection
- [ ] Validate props and state
- [ ] Sanitize before using
dangerouslySetInnerHTML - [ ] Use
rel="noopener"on external links - [ ] Implement proper error boundaries
- [ ] Avoid inline event handlers in JSX
- [ ] Use strict mode
- [ ] Validate dynamic component rendering
- [ ] Implement proper key management
- [ ] Avoid exposing sensitive data in Redux/state
- [ ] Use secure routing libraries
- [ ] Implement proper authentication guards
- [ ] Enable security logging
- [ ] Track auth failures
- [ ] Monitor unusual traffic patterns
- [ ] Set up alerts for security events
- [ ] Run security scans regularly
- [ ] Implement audit trails
- [ ] Monitor for data breaches
- [ ] Track API usage patterns
- [ ] Log all authentication events
- [ ] Monitor failed login attempts
- [ ] Track privilege escalation attempts
- [ ] Implement real-time alerting
- [ ] Use SIEM tools
- [ ] Monitor third-party integrations
- [ ] Track CSP violations
- [ ] Implement anomaly detection
- [ ] Review logs regularly
- [ ] Set up incident response plan
- [ ] Implement GDPR compliance (if applicable)
- [ ] Add privacy policy
- [ ] Implement cookie consent
- [ ] Enable data export functionality
- [ ] Implement right to deletion
- [ ] Encrypt PII at rest
- [ ] Encrypt PII in transit
- [ ] Minimize data collection
- [ ] Implement data retention policies
- [ ] Anonymize analytics data
- [ ] Secure third-party data processors
- [ ] Implement CCPA compliance (if applicable)
- [ ] Conduct privacy impact assessments
- [ ] Implement data breach notification
- [ ] Secure user data backups
- [ ] Implement access controls for PII
- β Storing tokens in localStorage
- β Over-permissive CORS (
Access-Control-Allow-Origin: *) - β No Content Security Policy
- β Blind trust in frontend validation
- β Exposed API keys in code
- β Hardcoded credentials
- β Using HTTP instead of HTTPS
- β Ignoring
npm auditwarnings - β No rate limiting
- β Exposing internal error messages
- β Using deprecated security headers
- β Not validating redirects
- β Trusting user input
- β Weak session management
- β Missing CSRF protection
- β Insecure direct object references
- β Using weak encryption
- β Not implementing MFA
- β Exposing stack traces in production
- β No security headers
- [ ] Test authentication flows
- [ ] Test authorization bypass
- [ ] Test XSS vulnerabilities
- [ ] Test CSRF protection
- [ ] Test input validation
- [ ] Test session management
- [ ] Test file upload security
- [ ] Test API endpoints
- [ ] Test error handling
- [ ] Test password reset flows
- [ ] Run SAST (Static Application Security Testing)
- [ ] Run DAST (Dynamic Application Security Testing)
- [ ] Use security linters (ESLint security plugins)
- [ ] Implement dependency scanning
- [ ] Use vulnerability scanners
- [ ] Run penetration tests
- [ ] Implement fuzz testing
- [ ] Use OWASP ZAP or Burp Suite
- [ ] Automated security in CI/CD
- [ ] Container security scanning
Client-side code can be modified, bypassed, or reverse-engineered. Always validate and enforce security server-side.
Client-side validation is for UX only. All inputs, authentication, and authorization must be validated on the server.
Grant minimum necessary permissions. Users, APIs, and services should only have access to what they need.
Design systems assuming attackers may gain partial access. Implement defense in depth with multiple security layers.
Include security from the start, not as an afterthought. Security should be part of every feature discussion.
Complex security implementations are error-prone. Use established, tested security patterns and libraries.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Set-Cookie: token=...;
HttpOnly;
Secure;
SameSite=Strict;
Max-Age=3600;
Path=/;
Domain=example.comContent-Security-Policy:
default-src 'none';
script-src 'self' 'nonce-{random}';
style-src 'self' 'nonce-{random}';
img-src 'self' https: data:;
font-src 'self';
connect-src 'self';
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
upgrade-insecure-requests;
block-all-mixed-content;
Access-Control-Allow-Origin: https://trusted-domain.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400# Run npm audit
npm audit
npm audit fix
# Check for outdated packages
npm outdated
# Security linting
npx eslint --plugin security .
# OWASP Dependency Check
dependency-check --project myapp --scan .
# Check TLS configuration
nmap --script ssl-enum-ciphers -p 443 example.com
# Test security headers
curl -I https://example.com | grep -E "Strict-Transport|Content-Security|X-Frame"
# Check for exposed secrets
trufflehog filesystem /path/to/repo
# Scan Docker images
docker scan myimage:latestRun before every production deployment:
- β All authentication flows tested
- β Authorization checks in place
- β Input validation on all endpoints
- β Security headers configured
- β CSP implemented and tested
- β HTTPS enforced
- β Secrets removed from code
- β npm audit shows no critical issues
- β Rate limiting enabled
- β Error messages sanitized
- β Monitoring and alerting configured
- β Security scan passed
- β Third-party scripts reviewed
- β Cookies configured securely
- β CORS properly restricted
- Security Scanners: OWASP ZAP, Burp Suite, Nessus
- Dependency Checking: Snyk, npm audit, Dependabot
- Header Testing: securityheaders.com, Mozilla Observatory
- SSL Testing: SSL Labs, testssl.sh
- CSP Testing: CSP Evaluator, report-uri.com
- NIST Cybersecurity Framework
- ISO 27001
- PCI DSS (for payment processing)
- SOC 2
Weekly:
- Review dependency updates
- Check security alerts
- Review access logs
Monthly:
- Run security scans
- Update dependencies
- Review security policies
- Test authentication flows
Quarterly:
- Penetration testing
- Security training
- Policy review
- Incident response drill
Annually:
- Comprehensive security audit
- Third-party assessment
- Update security documentation
- Review and update disaster recovery plan