Security Basics
Simple habits that keep a Node app safe.
Syntax
npm audit
npm audit fixSecurity is a habit, not an afterthought. A few essentials for Node apps:
- Never commit secrets — use environment variables.
- Validate input — never trust data from users.
- Keep dependencies updated — run
npm auditto find known vulnerabilities. - Avoid dangerous functions — never pass user input to
evalor shell commands. - Use HTTPS in production.
Example
# Check installed packages for known vulnerabilities
npm audit
# Automatically update to safe versions where possible
npm audit fix
# See outdated packages
npm outdatedWhen to use it
- A web API validates all incoming request bodies with `zod` before passing them to the database layer, rejecting malformed or oversized payloads early.
- A developer scans the project's dependencies with `npm audit` in CI to block deploys when packages with known CVEs are found.
- An HTTP API uses `helmet` to set security headers that prevent clickjacking, MIME-sniffing, and XSS on all responses.
More examples
Set security headers with helmet
Adds `helmet` middleware which automatically sets headers like `X-Frame-Options`, `Strict-Transport-Security`, and CSP.
const express = require('express');
const helmet = require('helmet');
const app = express();
app.use(helmet()); // sets 12+ security headers
app.get('/', (req, res) => res.json({ ok: true }));
app.listen(3000);Validate input with zod
Uses `zod` to validate and type-check request body fields, returning a 422 with structured errors on failure.
const { z } = require('zod');
const UserSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().min(0).max(150),
});
const result = UserSchema.safeParse(req.body);
if (!result.success) {
return res.status(422).json(result.error.format());
}Rate-limit an endpoint
Applies `express-rate-limit` to all `/api/` routes to prevent brute-force and denial-of-service attacks.
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // requests per window
standardHeaders: true,
message: { error: 'Too many requests' },
});
app.use('/api/', limiter);
Discussion