Transport encryption: HTTPS/TLS
HTTPS is HTTP over TLS (Transport Layer Security). It encrypts the traffic between client and server, guarantees integrity (nobody alters the data in transit) and authenticity (the certificate proves you are talking to the real server, not to an attacker in the middle). In production, everything goes over HTTPS: passwords, session tokens and cookies travel in plaintext without it.
Reinforce it with the HSTS header (Strict-Transport-Security), which forces
the browser to always use HTTPS for your domain.
CORS: who can call your API
The browser enforces the same-origin policy: by
default, a page on a.com cannot read responses from an API on b.com.
CORS (Cross-Origin Resource Sharing) is the mechanism by which the server
explicitly authorizes specific origins with headers like
Access-Control-Allow-Origin. Don't use * with credentials: list only the
trusted origins.
CSP: Content Security Policy
The Content-Security-Policy header declares which sources the
browser may load scripts, styles and images from. It is the strongest defense against
XSS: even if an attacker injects <script>, the browser refuses to
execute it if it doesn't come from an allowed source.
Content-Security-Policy: default-src 'self'; script-src 'self'
Security headers: helmet
In Express, helmet is a middleware that sets a whole set of
sensible security headers at once (CSP, HSTS, X-Content-Type-Options,
X-Frame-Options against clickjacking, etc.):
const helmet = require("helmet");
app.use(helmet());
OWASP Top: the classic risks
The OWASP Top 10 lists the most common web risks. Three essentials:
SQL injection. Concatenating user input inside a query lets arbitrary SQL run. The defense is to use parameterized queries (prepared statements): the data travels separately from the SQL text and is never interpreted as code.
// ❌ vulnerable: concatenates the input db.query("SELECT * FROM users WHERE email = '" + email + "'"); // ✅ parameterized: the driver escapes the value db.query("SELECT * FROM users WHERE email = $1", [email]);XSS (Cross-Site Scripting). The attacker gets the victim's browser to execute their JavaScript by injecting it into a page. It is prevented by escaping (converting to HTML entities) any user data before rendering it, and reinforced with CSP.
CSRF (Cross-Site Request Forgery). A malicious site causes the victim's already-authenticated browser to send a request to your API taking advantage of its cookies. It is mitigated with CSRF tokens and
SameSitecookies.
Sanitizing and escaping inputs
Golden rule: validate the input (reject what doesn't match what's expected), sanitize (remove the dangerous parts) and escape on output depending on the context (HTML, SQL, shell). Escaping at render time is what neutralizes XSS.
Secrets management and dependency scanning
Keys, passwords and tokens are never written in the code nor pushed
to the repository: they go in environment variables or in a secrets manager
(Vault, AWS Secrets Manager). And since most of your code is
third-party dependencies, scan them for known vulnerabilities with
npm audit (and tools like Dependabot or Snyk) continuously.