Hard20 minExpress.js Fundamentals
UpdatedAug 5, 2026
Edit

Express Security Basics

Question Variations

  • "What does Helmet protect, and what does it not protect?"
  • "Why is a permissive CORS configuration risky with credentialed requests?"
  • "How does a multi-instance deployment change rate limiting?"

Why This Is Asked

An Express application exposes Node.js and application data directly to the network. This question checks whether you can layer protections instead of relying on a single package or header.

Key Concepts

  • Security headers, transport security, input validation, and authorization address different threats.
  • CORS controls browser cross-origin access; it is not authentication or a server-side access-control mechanism.
  • Rate limits must be scoped and backed by shared state when the application is horizontally scaled.
  • Secrets and detailed error information must not be returned to clients.

Question Variations

  • “What does Helmet protect, and what does it not protect?”
  • “Why is a permissive CORS configuration risky with credentialed requests?”
  • “How does a multi-instance deployment change rate limiting?”

Answers by Technology

+ Add Variant
Express.jsImprove this answer ✏️

Expected Answer (Express 5.1.0 / Node.js 18+)

Secure an Express service in layers. Terminate or enforce TLS, set security headers with a maintained middleware such as Helmet, validate and allow-list inputs, authenticate requests, and perform authorization on every protected resource. Configure CORS with explicit allowed origins and methods; CORS is enforced by browsers and does not authorize non-browser clients. Use rate limits for abuse-prone endpoints, but store counters in shared infrastructure when multiple instances serve traffic.

Production error responses must be generic and must not reveal stacks, secrets, SQL, or internal topology. Keep secrets out of source control and inject them through a managed runtime configuration mechanism. Log a correlation ID and safe operational context server-side, rather than returning debugging detail to the client.

Why It Matters

Most production incidents exploit gaps between controls: a header cannot compensate for missing authorization, and CORS cannot protect a public API from a script or curl request.

Code Example

import express, { NextFunction, Request, Response } from 'express';

const app = express();
app.use((req: Request, res: Response, next: NextFunction) => {
  res.set('X-Content-Type-Options', 'nosniff');
  res.set('X-Frame-Options', 'DENY');
  return next();
});
app.use((req: Request, res: Response, next: NextFunction) => {
  const origin = req.get('origin');
  if (origin === 'https://app.example.com') res.set('Access-Control-Allow-Origin', origin);
  return next();
});
app.get('/health', (req: Request, res: Response) => res.json({ ok: true }));
app.listen(3000);

Common Mistakes

  • Using Access-Control-Allow-Origin: * with cookies: Browsers reject wildcard credentials, and permissive origin reflection can expose data.
  • Using in-memory rate limits across replicas: Each process has a separate counter, so the effective limit grows with the fleet.

Follow-up Questions

  • Does Helmet replace output encoding? (Answer: No; headers reduce risk but do not make unsafe HTML or data handling safe.)
  • Why log a request ID? (Answer: It connects a client-visible failure to safe server-side diagnostic events.)