Most security breaches don't happen because attackers are brilliant. They happen because developers made small, predictable mistakes under time pressure. The good news: a handful of habits eliminates the vast majority of common vulnerabilities.
Never trust input
Every value that enters your system from outside — form fields, URL params, HTTP headers, file uploads — is hostile until proven otherwise. Validate type, length, format, and range at the boundary. Reject early, fail loudly.
Parameterise every query
SQL injection is still in the OWASP Top 10 in 2026. This tells you how common it is. Never concatenate user input into a query string:
// Wrong
db.query(`SELECT * FROM users WHERE email = '${email}'`);
// Right
db.query('SELECT * FROM users WHERE email = $1', [email]);Every major database library supports parameterised queries. Use them, always.
Least privilege everywhere
Your API server doesn't need a database user with DROP TABLE privileges. Your frontend doesn't need write access to your storage bucket. Give each component only the permissions it needs to do its job. A compromised component then has a limited blast radius.
Log what matters, not everything
Log authentication events (login, logout, failed attempts), permission checks, and data mutations. Don't log passwords, tokens, or PII. Logs are often the only forensic record you have after an incident — make sure they contain the signal, not the noise.
Keep dependencies updated
A significant portion of vulnerabilities are in third-party packages, not your own code. Run npm audit regularly. Set up Dependabot or Renovate. Outdated dependencies are a known attack vector that costs nothing to close.