Skip to main content
Back to blog
April 28, 2026|8 min read|Antoine Duno

Web Security for Developers: The 10-Point Checklist for Every Project in 2026

Web security for developers in 2026 comes down to ten practices applied consistently on every project. This checklist covers what to implement, why it matters, and how to verify it.

ZeriFlow Team

1,878 words

Web Security for Developers: The 10-Point Checklist for Every Project in 2026

Web security for developers is not a specialty track — it is a baseline professional skill. Every project you ship, whether it is a marketing site, a SaaS product, or an internal tool, benefits from the same foundational controls. The ten practices below cover the full stack from infrastructure to application to CI/CD, and they are applicable regardless of framework or language.

Scan your site in 60 seconds — it's free: ZeriFlow →

1. HTTPS Everywhere, Properly Configured

This is table stakes in 2026, but getting it right matters more than just having a certificate.

What "properly configured" means: - TLS 1.2 minimum, TLS 1.3 preferred - HTTP → HTTPS redirect (301, permanent) on all domains including www and non-www variants - HSTS header with at minimum max-age=31536000; includeSubDomains - Certificate auto-renewal configured and monitored (Let's Encrypt via Certbot or cloud-native cert managers) - No mixed content — every resource (images, scripts, fonts, API calls) loaded over HTTPS

Common mistakes: - HSTS set on the HTTP response (before redirect) — browsers ignore it there; it must be on the HTTPS response - HTTPS on the main domain but HTTP on subdomains (API, static assets, admin panel) - Short HSTS max-age that expires before the next deployment cycle


2. Security Headers on Every Response

Security headers are HTTP response headers that tell browsers how to behave when rendering your page. They are a client-side defense layer that costs nothing to implement and prevents several common attack classes.

Minimum set for any project:

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self'; frame-ancestors 'none';
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()

CSP is the most powerful and the most complex. For projects with lots of third-party scripts (analytics, chat, A/B testing), start with Content-Security-Policy-Report-Only to audit before enforcing.

Set headers at the infrastructure layer (nginx, CDN), not in application code — they apply to every response including error pages and static assets. Use ZeriFlow to verify headers are actually being served correctly in production.


Every cookie your application sets should be intentionally configured. Session tokens left without security flags are one of the easiest paths for an attacker to escalate from a minor XSS to a full account takeover.

For every cookie, ask: - Does it need to be read by JavaScript? If not → HttpOnly - Should it ever be sent over HTTP? Never → Secure - Should it be sent with cross-site requests? Probably not → SameSite=Strict or SameSite=Lax - How long should it live? Set Max-Age or Expires explicitly; session cookies expire on browser close but can be preserved by session restore

python
# FastAPI / Python example
response.set_cookie(
    key="session_id",
    value=session_token,
    httponly=True,
    secure=True,
    samesite="strict",
    max_age=3600,
    path="/",
)

Never store sensitive tokens (JWTs with auth claims, session IDs) in localStorage or sessionStorage — they are accessible to any JavaScript on the page, including injected XSS payloads.


4. Authentication Done Right

Authentication failures are the most common root cause of significant breaches. These are the non-negotiables:

  • Password hashing: bcrypt (cost factor 12+), Argon2id, or scrypt. Never MD5, SHA-1, or unsalted SHA-256.
  • MFA: Offer it. For any application handling personal data or financial information, make it the default or mandatory.
  • Rate limiting on auth endpoints: 5–10 attempts per IP per 15 minutes with exponential backoff. See our dedicated guide on API rate limiting for implementation details.
  • Secure password reset: Token-based, single-use, expiring links (30–60 minutes). Never send passwords in plaintext emails. Never use security questions.
  • JWT security: Short expiry (15 minutes for access tokens), store refresh tokens in HttpOnly cookies (not localStorage), validate the alg field explicitly (reject alg: none).

5. Input Validation and Output Encoding

The XSS/SQLi/command injection family of vulnerabilities is older than most working developers and still appears in new codebases weekly.

The principle: Never trust user input. Validate it on entry; encode it on output.

SQL injection: Use parameterized queries or ORM-level query builders. Never concatenate user input into SQL strings.

python
# Vulnerable
cursor.execute(f"SELECT * FROM users WHERE email = '{user_input}'")

# Safe
cursor.execute("SELECT * FROM users WHERE email = %s", (user_input,))

XSS: Output-encode user-controlled data when rendering HTML. Modern frameworks (React, Vue, Angular) escape by default — but watch for explicit bypass patterns (dangerouslySetInnerHTML, v-html, [innerHTML]) used with user-controlled data.

Command injection: Avoid shell execution with user input. If unavoidable, use argument arrays rather than string interpolation, and validate input against a strict allowlist.

File uploads: Validate MIME type server-side (not just file extension), scan with an antivirus library if storing, never store in webroot, generate a random filename rather than using the user-supplied name.


6. Dependency Management

Your application's attack surface includes every package in your package.json, requirements.txt, Gemfile, or go.mod. In 2025, supply chain attacks via compromised npm packages accounted for a meaningful proportion of new vulnerabilities disclosed.

Practices: - Run npm audit, pip-audit, or snyk test in CI — fail the build on high/critical vulnerabilities - Pin dependency versions (use lockfiles — package-lock.json, poetry.lock, Cargo.lock) - Enable Dependabot or Renovate for automated dependency update PRs - Review new dependencies before adding them: check download count, maintenance status, and GitHub stars as proxies for legitimacy - Use npm ci (clean install from lockfile) in CI, not npm install


7. Secrets Management

Secrets in code repositories are found by attackers within hours of exposure. GitHub's secret scanning service detected over 12 million new leaked secrets in 2024.

Rules: - No secrets in code — use environment variables - No secrets in docker-compose.yml, Makefile, or CI config files checked into version control - Use a secrets manager for production: AWS Secrets Manager, HashiCorp Vault, Doppler, or your cloud provider's equivalent - Rotate secrets on a schedule (quarterly for API keys, immediately on suspected compromise) - Add git-secrets or trufflehog as a pre-commit hook to prevent accidental commits

If you discover a secret was committed, treat it as compromised immediately — rotate it, then clean the git history. Cleaning git history is not sufficient alone because the secret may already have been scraped from public repositories within minutes of the push.


8. Logging and Monitoring

You cannot respond to incidents you cannot detect. Logging is the foundation of incident response.

What to log: - Authentication events (success, failure, MFA, password reset) - Authorization failures (403s on sensitive endpoints) - Input validation failures on security-sensitive parameters - Unexpected errors in production (often indicate probing) - Data export events

What not to log: - Passwords or password hashes - Session tokens or API keys - Full credit card numbers (log only last 4) - Unmasked personal data where not necessary

Where to send logs: Centralize them. Application logs on individual servers are lost when the server is terminated or compromised. Use a log aggregator: Datadog, Loki, CloudWatch Logs, or a self-hosted ELK stack. Set up alerts for authentication anomalies, error rate spikes, and geographic access patterns that deviate from normal.


9. CI/CD Security Integration

Security checks that run manually are security checks that get skipped under deadline pressure. Build them into the pipeline so they are automatic.

CI security checks to add today: - npm audit --audit-level=high or snyk test — fail on high/critical CVEs - SAST scanner (Semgrep, CodeQL, or Bandit for Python) — catches common vulnerability patterns in code - Secret scanning (trufflehog, git-leaks) — detect secrets before they reach the repo - Container image scanning (Trivy, Snyk Container) if you use Docker - Infrastructure-as-code scanning (Checkov, tfsec) if you use Terraform or CloudFormation

Post-deployment: Run a ZeriFlow scan as part of your deployment verification step. A deployment that silently drops a security header or changes a cookie configuration is a regression. Automating the check catches it immediately.


10. Continuous Monitoring

Security is not a project — it is a state you maintain. Configuration drift, new vulnerabilities in dependencies, and certificate expiry are ongoing concerns.

Ongoing monitoring stack: - Certificate expiry: Alert at 30 days, escalate at 7 days - Security header monitoring: Any deployment can silently overwrite headers — scan weekly or post-deploy - Dependency vulnerability feeds: Subscribe to GitHub Security Advisories for your language ecosystem - Uptime monitoring: Downtime can indicate an active attack (DDoS, compromise, certificate issue) - Error rate monitoring: A spike in 5xx errors after a deployment is a regression; a spike in 4xx errors from new IPs may be a probe


FAQ

Q: Which security header should I implement first if I'm starting from zero?

A: X-Content-Type-Options: nosniff — it is one line, has no compatibility issues, and immediately prevents MIME-sniffing attacks. Then add X-Frame-Options: DENY and Strict-Transport-Security. CSP is the most powerful but requires more tuning; save it for when you can spend an hour understanding your resource loading.

Q: Is it safe to store JWT tokens in localStorage?

A: For tokens that provide authentication (access tokens, refresh tokens), no. localStorage is accessible to any JavaScript on your page, including injected XSS payloads. A successful XSS attack can steal tokens from localStorage and use them from a different origin. Store auth tokens in HttpOnly, Secure, SameSite cookies. localStorage is appropriate for non-sensitive preference data.

Q: How do I handle CORS securely?

A: Set Access-Control-Allow-Origin to explicit allowed origins, never * for authenticated endpoints. Never use * with Access-Control-Allow-Credentials: true — browsers reject this combination anyway. Validate the Origin header server-side against your allowlist. For public APIs (no auth), * is acceptable.

Q: What is the minimum security setup for an internal tool?

A: VPN or IP allowlist instead of public exposure is the first choice. If it must be public: HTTPS, authentication on every endpoint, rate limiting, and basic security headers. "Internal tools" are disproportionately breached because teams assume they are low-risk and skip security basics.

Q: How do I convince management to invest time in security?

A: Translate to business risk: "A misconfigured session cookie means an attacker can take over any user account — that is a data breach, which triggers GDPR notification requirements and potential fines." The developer security checklist takes 2–4 hours of setup per project. The cost of not doing it is measured in incident response, customer notification, and legal fees.


Conclusion

Web security for developers in 2026 is a set of practices, not a product. HTTPS with proper TLS configuration, a minimal set of security headers, secure cookie flags, solid authentication, input validation, dependency scanning, secrets management, logging, CI security integration, and continuous monitoring. Ten practices, applied consistently, cover the vast majority of real-world attacks against web applications.

The fastest way to audit whether a live site has these controls in place at the infrastructure layer — headers, TLS, cookies, DNS, email security — is an automated scan.

Start your free ZeriFlow scan → — no credit card, instant results.

Ready to check your site?

Run a free security scan in 30 seconds.

Related articles

Keep reading