Web application security is not a feature you add at the end - it is a discipline you practice from day one. This guide covers the practices that have the highest impact for the effort, based on what we see in real production environments. Skip any of these and you are leaving the door open for attackers.
The Threat Landscape in 2025
The OWASP Top 10 has evolved. Injection vulnerabilities are down thanks to parameterized queries and ORMs. Broken authentication and sensitive data exposure are up, driven by the proliferation of APIs and the continued misuse of JWT. Supply chain attacks - compromised dependencies - are now a top concern.
Authentication and Authorization
Authentication (who you are) and authorization (what you can do) are the foundation of web app security. Get these wrong and nothing else matters. The good news is that the right patterns are well-established - the bad news is that teams still cut corners.
- →Use a battle-tested auth provider (Auth0, Clerk, AWS Cognito) instead of rolling your own
- →Enforce MFA for any account with elevated privileges
- →Hash passwords with bcrypt or argon2 - never MD5, never SHA-256 alone
- →Use short-lived access tokens + refresh tokens, not long-lived sessions
- →Validate authorization on every request, not just at login
Never store secrets in JWTs
JWTs are base64-encoded, not encrypted. Anyone who intercepts the token can read its contents. Never put passwords, API keys, or PII in a JWT payload. If you need to store sensitive data, use server-side sessions or encrypted claims.
Input Validation and Output Encoding
Most web vulnerabilities - XSS, SQL injection, command injection, path traversal - come down to one root cause: untrusted input being used without validation or proper encoding. The fix is simple in principle: validate everything coming in, encode everything going out.
// Bad - vulnerable to SQL injection
const sql = `SELECT * FROM users WHERE email = '${email}'`;
// Good - parameterized query
const sql = 'SELECT * FROM users WHERE email = $1';
const result = await db.query(sql, [email]);For XSS prevention, the rule is to always contextually encode output. Modern frameworks like React escape by default, which eliminates most XSS vectors. The danger is when you bypass that escaping with dangerouslySetInnerHTML or similar - only do this with content you fully trust.
API Security Fundamentals
APIs are the new attack surface. They are often less protected than web UIs because they were built for machine-to-machine communication. But APIs expose the same sensitive data and operations, and attackers know it.
- 1Rate limit every endpoint - both per-user and globally
- 2Validate input schemas with a library like Zod or Joi
- 3Use CORS allowlists, not wildcard origins
- 4Log and monitor API access for unusual patterns
- 5Version your APIs so you can deprecate vulnerable endpoints
Dependency Management
Your app's attack surface includes every dependency you install. The npm ecosystem alone has over 2 million packages, and supply chain attacks - where a dependency is compromised - are increasing. The fix is visibility and process.
- →Run npm audit or Snyk regularly and fix high-severity vulnerabilities
- →Pin dependency versions with lockfiles - never use floating ranges in production
- →Review new dependencies before adding them - is the package maintained? Widely used?
- →Use Dependabot or Renovate to automate security updates
Monitoring and Incident Response
You cannot defend against what you cannot see. Monitoring is the difference between catching an attack in minutes versus discovering it months later in a breach notification. Every production app should log security-relevant events, alert on anomalies, and have a documented incident response plan.
Have a breach plan before you need it
The worst time to figure out your incident response is during an incident. Write the runbook now: who to contact, how to communicate, how to revoke credentials, how to preserve evidence. Practice it once a year. The teams that handle breaches well are the ones that rehearsed.
Security as a Culture
Tools and processes matter, but security is ultimately a culture. When every engineer thinks about security by default - questions every assumption, reviews every PR for risks, reports every suspicious activity - you build resilience that no tool can provide. Invest in training, celebrate good catches, and make security part of how your team works, not a separate checklist.
Usman Ghani
DevOps Lead at HMCoders
Usman is part of the HMCoders team, helping businesses ship world-class digital products. This article reflects patterns and lessons learned from real client engagements.

