BD Brian Detering Professor of Programming – University of Southern California
Security

How to Secure Your Web App: A Practical Checklist for Developers

Brian Detering
Brian Detering Tech Writer & Developer

Most web application security incidents are not the result of sophisticated zero-day exploits. They are the result of skipped basics — exposed secrets, outdated dependencies, missing rate limiting, default configurations left unchanged. This checklist covers the things that actually get applications compromised, in rough order of how often they are exploited.

Authentication and session management

  • Use a battle-tested auth library — do not roll your own session management. Auth0, Clerk, Supabase Auth, and similar services handle the edge cases that custom implementations routinely miss.
  • Enforce MFA for admin accounts — especially for accounts with access to user data, billing, or infrastructure.
  • Set appropriate session timeouts — and invalidate sessions on password change, logout, and privilege escalation.
  • Rate limit login endpoints — exponential backoff after failed attempts. A login endpoint with no rate limiting is an open invitation for credential stuffing.
  • Use secure, HttpOnly, SameSite cookies — for session tokens. Never store session data in localStorage.

Secrets and environment variables

  • Never commit secrets to version control — add .env to your .gitignore before your first commit, not after you accidentally push your API key.
  • Rotate compromised secrets immediately — assume any secret that touched a public repository is compromised, regardless of how briefly it was exposed.
  • Use a secrets manager in production — AWS Secrets Manager, HashiCorp Vault, Doppler, or 1Password Secrets Automation. Environment variable injection at deploy time is preferable to baking secrets into container images.
  • Scan for leaked secrets in CI — tools like Trufflehog or Gitleaks can catch accidental commits before they merge.

Dependencies and supply chain

Supply chain attacks caused over $60 billion in damage in 2025, according to OX Security’s 2026 research — tripling from 2021. Your dependencies are an attack surface.

  • Enable Dependabot or Renovate — automated dependency update PRs with security advisories. The overhead of reviewing update PRs is much lower than the overhead of responding to a breach.
  • Pin dependency versions in productionnpm ci instead of npm install, lock files committed to version control.
  • Audit your dependency treenpm audit, pip-audit, or equivalent. Not every critical vulnerability will trigger an automated PR.
  • Be selective with new dependencies — a package with 3 stars, no recent commits, and access to your file system is a risk. Check download counts, maintenance status, and permissions before adding.

HTTP security headers

These are trivially easy to set and widely skipped. Add them to your response headers:

  • Content-Security-Policy — restrict which sources can load scripts, styles, and other resources. Mitigates XSS significantly.
  • Strict-Transport-Security — enforce HTTPS and prevent protocol downgrade attacks.
  • X-Frame-Options: DENY — prevent clickjacking.
  • X-Content-Type-Options: nosniff — prevent MIME-type sniffing.
  • Referrer-Policy: strict-origin-when-cross-origin — control what URL information leaks in requests.

Run your deployed app through securityheaders.com — it takes 30 seconds and shows exactly what is missing.

Input validation and SQL injection

  • Use parameterized queries — every modern ORM does this by default. If you are concatenating user input into SQL strings, stop.
  • Validate and sanitize all user input — on the server side. Client-side validation is a UX feature, not a security control.
  • Use an allowlist, not a blocklist — for input validation. Blocking known-bad patterns is a losing game; allowing only known-good patterns is not.

Infrastructure basics

  • Disable directory listing — on your web server.
  • Remove default credentials — on every service before it reaches a network.
  • Use HTTPS everywhere — including internal service-to-service communication.
  • Restrict database access by IP — your database should not be publicly accessible.
  • Enable access logging — you cannot investigate an incident without logs. CloudWatch, Datadog, or a self-hosted ELK stack all work.

None of this is exotic. Most of it takes an afternoon to implement. The gap between “reasonably secure” and “actively vulnerable” is smaller than most developers think.

Related: best VPNs for developers and the security tools worth paying for.

Brian Detering

About Brian Detering

Brian Detering is a software engineer, educator, and tech writer based in Los Angeles. He teaches programming and software engineering at the University of Southern California, where his work spans programming languages, systems architecture, and applied AI. With over a decade of hands-on experience building production systems, Brian writes about the tools and workflows that actually make developers more productive — from CI/CD pipelines and containerization to API testing and security best practices. When he's not teaching or writing code, he's usually benchmarking the latest dev tools or tinkering with homelab infrastructure.

Related Articles