Facebook Pixel

Node.js Security Interview Questions Authentication, Injection, and Best Practices

Master Node.js security interview questions JWT, cookies, NoSQL injection, XSS, CSRF, and production security best practices.

Node.js Security Interview Questions

Security is critical in any Node.js application. Here are the most common interview questions.

Q1: How Do You Implement Authentication in Node.js?

Answer:

  1. JWT Sign a token with user ID, verify on each request
  2. Cookies Store JWT in HTTP-only cookie (XSS-safe)
  3. Middleware Verify JWT on protected routes
// Sign token const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, { expiresIn: "7d" }); // Set cookie res.cookie("token", token, { httpOnly: true, secure: true, sameSite: "strict" }); // Verify middleware const auth = (req, res, next) => { const token = req.cookies.token; const decoded = jwt.verify(token, process.env.JWT_SECRET); req.user = decoded; next(); };

Q2: What Is NoSQL Injection and How Do You Prevent It?

Answer: NoSQL injection occurs when user input is passed directly to MongoDB queries.

// VULNERABLE User.find({ email: req.body.email }); // If req.body.email is { $gt: "" }, it returns all users! // SAFE use express-mongo-sanitize const mongoSanitize = require("express-mongo-sanitize"); app.use(mongoSanitize()); // Removes $ and . from req.body // Or validate input if (typeof req.body.email !== "string") { return res.status(400).json({ message: "Invalid email" }); }

Q3: What Is XSS and How Do You Prevent It?

Answer: XSS (Cross-Site Scripting) injects malicious scripts into web pages.

Prevention:

  1. Escape HTML output Use a templating engine that escapes by default
  2. Content-Security-Policy Restrict script sources
  3. HTTP-only cookies Prevent JavaScript from accessing cookies
  4. Input validation Strip HTML tags from user input

Q4: What Is CSRF and How Do You Prevent It?

Answer: CSRF (Cross-Site Request Forgery) tricks users into making unwanted requests.

Prevention:

  1. sameSite cookies sameSite: "strict" or "lax"
  2. CSRF tokens Include a random token in forms
  3. Origin header check Verify the request origin

Q5: How Do You Store Passwords Securely?

Answer: Never store plain text passwords. Use bcrypt:

const bcrypt = require("bcrypt"); // Hash (during signup) const salt = await bcrypt.genSalt(10); const hashedPassword = await bcrypt.hash(password, salt); // Compare (during login) const isMatch = await bcrypt.compare(inputPassword, user.password);

Why bcrypt:

  • Salt Random value added to prevent rainbow table attacks
  • Slow Deliberately slow to resist brute-force
  • Adaptive Cost factor can be increased as hardware improves

Q6: What Security Headers Should You Set?

Answer:

// Using helmet (sets all security headers) const helmet = require("helmet"); app.use(helmet()); // Or manually: app.use((req, res, next) => { res.setHeader("X-Content-Type-Options", "nosniff"); res.setHeader("X-Frame-Options", "SAMEORIGIN"); res.setHeader("Strict-Transport-Security", "max-age=31536000"); next(); });

Q7: How Do You Rate Limit an API?

Answer:

const rateLimit = require("express-rate-limit"); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // 100 requests per window message: "Too many requests, please try again later." }); app.use("/api/", limiter);

The Takeaway

Security interview questions cover: authentication (JWT in HTTP-only cookies, auth middleware), NoSQL injection (express-mongo-sanitize, input validation), XSS (escape HTML, CSP, HTTP-only cookies), CSRF (sameSite cookies, CSRF tokens), password storage (bcrypt with salt and cost factor), security headers (helmet or manual X-Content-Type-Options, X-Frame-Options, HSTS), and rate limiting (express-rate-limit).

Sign a JWT with user ID using jwt.sign(), store in an HTTP-only cookie (secure: true, sameSite: 'strict'), and verify on each request with auth middleware (jwt.verify). HTTP-only cookies prevent JavaScript access (XSS-safe). Never store JWTs in localStorage.

NoSQL injection occurs when user input like { $gt: '' } is passed directly to MongoDB queries, returning all documents. Prevent with express-mongo-sanitize (removes $ and . from req.body), validate input types, and use Mongoose schema validation.

Never store plain text. Use bcrypt: genSalt(10) for a random salt, hash(password, salt) for the hash, and compare(inputPassword, storedHash) for verification. bcrypt is deliberately slow (resists brute-force) and uses salts (prevents rainbow table attacks).

Use helmet() for all headers, or set manually: X-Content-Type-Options (nosniff), X-Frame-Options (SAMEORIGIN, prevents clickjacking), Strict-Transport-Security (HSTS, forces HTTPS), Content-Security-Policy (restricts script sources), and X-XSS-Protection.

Use sameSite cookies (sameSite: 'strict' or 'lax' prevents cross-site requests), CSRF tokens (random token in forms, verified server-side), and verify the Origin header matches your domain. sameSite cookies are the simplest and most effective.

Ready to master Node.js completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.