Node.js8 min read

Security Best Practices

Secure your Node.js app. Learn Helmet, input validation, and common vulnerabilities.

Michael Torres
December 19, 2025
0.0k0

Security Best Practices

Use Helmet for Security Headers

npm install helmet
const helmet = require('helmet');

app.use(helmet());

Helmet sets HTTP headers to protect against:

  • XSS attacks
  • Clickjacking
  • MIME sniffing
  • And more

Input Validation

npm install joi
const Joi = require('joi');

const userSchema = Joi.object({
  email: Joi.string().email().required(),
  password: Joi.string().min(8).required(),
  age: Joi.number().integer().min(18)
});

app.post('/register', async (req, res) => {
  try {
    const validated = await userSchema.validateAsync(req.body);
  } catch (error) {
    return res.status(400).json({ error: error.details[0].message });
  }
});

Prevent SQL Injection

const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [req.params.id]);

const user = await User.findById(req.params.id);

Secure Password Storage

const bcrypt = require('bcrypt');

const hash = await bcrypt.hash(password, 10);

Environment Variables

require('dotenv').config();

const secret = process.env.JWT_SECRET;

Rate Limiting

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100
});

app.use('/api/', limiter);

HTTPS Only

app.use((req, res, next) => {
  if (req.header('x-forwarded-proto') !== 'https') {
    return res.redirect(`https://${req.header('host')}${req.url}`);
  }
  next();
});

Key Takeaway

Use Helmet for security headers. Validate all input. Use parameterized queries. Hash passwords with bcrypt. Never commit secrets. Enable rate limiting. Use HTTPS in production.

#Node.js#Security#Helmet#Validation