Loading

Quipoin Menu

Learn • Practice • Grow

express-js / ExpressJS Security Practices
tutorial

ExpressJS Security Practices

Imagine you're building a house. You wouldn't just put up walls and a roof you'd install locks on doors, security cameras, and maybe even an alarm system. Similarly, when building web applications, you need multiple layers of security to protect your users' data and your application from attacks.

Common Web Security Threats

Before learning how to secure your Express app, understand what you're protecting against:
  • XSS (Cross-Site Scripting) Injecting malicious scripts into web pages.
  • CSRF (Cross-Site Request Forgery) Tricking users into performing unwanted actions.
  • SQL/NoSQL Injection Injecting malicious database queries.
  • Brute Force Attacks Trying many passwords to guess credentials.
  • Man-in-the-Middle Intercepting communication between client and server.
  • DDoS Overwhelming server with requests.

Essential Security Middleware: Helmet

Helmet helps secure your Express app by setting various HTTP headers. It's like a security guard for your HTTP responses.
npm install helmet
const helmet = require('helmet');
app.use(helmet());
That's it! Helmet automatically sets headers like X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, etc.

Preventing XSS Attacks
  • Use Helmet to set proper headers.
  • Escape user input when rendering HTML (templating engines do this automatically).
  • Use <%= %> in EJS (escapes HTML) instead of <%- %> (raw).
  • Validate and sanitize all user inputs.
  • Set HttpOnly cookies to prevent JavaScript access.

Preventing CSRF Attacks
CSRF attacks trick users into submitting requests they didn't intend. Use the csurf middleware.
npm install csurf
const csrf = require('csurf');
const cookieParser = require('cookie-parser');

app.use(cookieParser());
app.use(csrf({ cookie: true }));

// Add CSRF token to forms
app.get('/form', (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});

Preventing Injection Attacks
  • Always use parameterized queries or ORMs never concatenate user input directly into queries.
  • For SQL: use placeholders (?, $1) with drivers like mysql2 or pg.
  • For MongoDB: Mongoose automatically sanitizes input, but still validate.
  • Validate input types and lengths.
// BAD - vulnerable to SQL injection
const query = `SELECT * FROM users WHERE email = '${email}'`;

// GOOD - parameterized query
const [rows] = await pool.query('SELECT * FROM users WHERE email = ?', [email]);

Secure Password Storage
  • Always hash passwords with bcrypt (as covered in previous chapter).
  • Use appropriate salt rounds (10-12 is good).
  • Never store passwords in plain text.

HTTPS and Secure Cookies
// In production, use secure cookies
app.use(session({
secret: 'secret',
cookie: {
secure: true, // Only send over HTTPS
httpOnly: true, // Prevent JavaScript access
sameSite: 'strict' // CSRF protection
}
}));

Input Validation with Express-validator
Never trust user input. Use express-validator to validate and sanitize.
npm install express-validator
const { body, validationResult } = require('express-validator');

app.post('/register',
body('email').isEmail().normalizeEmail(),
body('password').isLength({ min: 6 }),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Process valid input
}
);

Environment Variables for Secrets
Never hardcode secrets in your code. Use environment variables.
// .env file
JWT_SECRET=your-super-secret-key
DB_PASSWORD=securepassword

// In code
const jwtSecret = process.env.JWT_SECRET;

Two Minute Drill
  • Use Helmet to set secure HTTP headers automatically.
  • Prevent XSS by escaping output and using HttpOnly cookies.
  • Prevent CSRF with csurf middleware and sameSite cookies.
  • Always use parameterized queries to prevent injection.
  • Validate and sanitize all user input.
  • Use HTTPS in production with secure cookies.
  • Store secrets in environment variables, never in code.
  • Security is a process, not a one-time setup stay updated!

Need more clarification?

Drop us an email at career@quipoinfotech.com