🌍 NodeJS · subject

NodeJS Security Syllabus

The Security syllabus for NodeJS in full: 3 chapters and 8 topics, every one listed below, plus 50 Security flashcards with answers.

3Chapters
8Topics
50Flashcards

Security syllabus: all 3 chapters

Expand any chapter to see its topics and sub-topics.

  1. Authentication

    3 topics
    • JWT (JSON Web Tokens)
    • OAuth
    • PassportJS
  2. Data Validation

    2 topics
    • Joi
    • Validator.js
  3. Common Security Practices

    3 topics
    • Helmet
    • Rate Limiting
    • CORS

NodeJS Security flashcards — 50 questions with answers

  1. What does JWT stand for, and what is its core purpose?

    JWT stands for JSON Web Token. It is a compact, URL-safe, self-contained token format (RFC 7519) used to securely transmit claims between parties as a digitally signed JSON object, commonly for stateless authentication and authorization.

  2. What are the three parts of a JWT, and how are they separated?

    A JWT has three Base64URL-encoded parts separated by dots: Header.Payload.Signature. The header declares the token type and signing algorithm, the payload holds the claims, and the signature verifies integrity.

  3. How is a JWT signature computed for an HMAC-based algorithm like HS256?

    The signature is HMAC-SHA256 over the encoded header and payload using a secret key: $$\text{signature} = \text{HMACSHA256}\big(\text{base64url}(header) + \texttt{.} + \text{base64url}(payload),\; secret\big)$$

  4. In JWT, what is the difference between symmetric (HS256) and asymmetric (RS256) signing?

    HS256 uses a single shared secret for both signing and verification (HMAC). RS256 uses an RSA private key to sign and a public key to verify, so verifiers never need the signing secret. Use RS256 when multiple/untrusted services must verify tokens.

  5. List common JWT registered (standard) claims and their meaning.

    iss (issuer), sub (subject/user), aud (audience), exp (expiration time), nbf (not before), iat (issued at), and jti (unique token ID). These are optional but standardized reserved claim names.

  6. Is data inside a standard (signed) JWT confidential? Why or why not?

    No. A signed JWT (JWS) only guarantees integrity and authenticity, not confidentiality; the payload is Base64URL-encoded, not encrypted, so anyone can decode it. For confidentiality you must use JWE (encrypted JWT) or transport over TLS and avoid storing secrets in the payload.

  7. What is the critical JWT vulnerability related to the alg header, and how is it prevented?

    The alg:none / algorithm-confusion attack: an attacker sets the header algorithm to none (unsigned) or swaps RS256 for HS256 to trick verification. Prevent it by explicitly whitelisting the expected algorithm(s) on verification and never trusting the alg field from the token.

  8. Explain the access token vs refresh token pattern in JWT-based auth.

    An access token is short-lived (e.g. minutes) and sent with each request to authorize API access. A refresh token is long-lived and stored securely; when the access token expires, the client presents the refresh token to obtain a new access token without re-logging in.

  9. Why are JWTs described as stateless, and what is the tradeoff for revocation?

    They are stateless because the server validates a token by checking its signature and claims without a session store lookup. The tradeoff: you cannot easily revoke a valid unexpired JWT, so revocation requires short expiry, a denylist/blocklist, or a token-version check.

  10. What is OAuth 2.0, and what problem does it solve?

    OAuth 2.0 is an authorization framework (RFC 6749) that lets a third-party application obtain limited access to a user's resources on another service without the user sharing their password. It issues scoped access tokens instead of exposing credentials.

  11. Name the four roles defined in the OAuth 2.0 framework.

    Resource Owner (the user), Client (the app requesting access), Authorization Server (issues tokens after authenticating the owner), and Resource Server (hosts the protected resources and accepts access tokens).

  12. What is the key distinction between authentication and authorization, and which does plain OAuth 2.0 provide?

    Authentication verifies who a user is; authorization determines what an entity is allowed to do. OAuth 2.0 is an authorization framework. Authentication on top of it is provided by OpenID Connect (OIDC), which adds an ID token.

  13. Describe the OAuth 2.0 Authorization Code grant flow at a high level.

    The client redirects the user to the authorization server, the user authenticates and consents, the server redirects back with a short-lived authorization code, and the client exchanges that code (server-to-server, with its client secret) for an access token.

  14. What is PKCE in OAuth 2.0, and why is it used?

    PKCE (Proof Key for Code Exchange, RFC 7636) secures the Authorization Code flow for public clients (SPAs, mobile). The client sends a hashed code_challenge up front and the plain code_verifier at token exchange, preventing authorization-code interception attacks. It is now recommended for all clients.

  15. What is the difference between an OAuth access token and an OIDC ID token?

    An access token authorizes API calls to the resource server (opaque to the client). An ID token is a JWT issued by OpenID Connect that authenticates the user and contains identity claims (sub, name, email) meant to be consumed by the client.

  16. What are OAuth scopes?

    Scopes are strings that define and limit the specific permissions an access token grants (e.g. read:profile, write:email). They implement least-privilege by restricting what the client can do on the resource server.

  17. Which OAuth 2.0 grant type is recommended for machine-to-machine (no user) access?

    The Client Credentials grant, where the client authenticates with its own client ID and secret to obtain an access token for its own resources, with no resource-owner involvement.

  18. What is PassportJS?

    Passport is authentication middleware for Node.js/Express. It provides a unified API to authenticate requests using pluggable 'strategies' (local, JWT, OAuth providers, etc.), decoupling auth logic from the application.

  19. In PassportJS, what is a 'strategy'?

    A strategy is a pluggable module that implements a specific authentication mechanism (e.g. passport-local for username/password, passport-jwt for JWTs, passport-google-oauth20 for Google). You configure strategies and Passport delegates authentication to them.

  20. What do serializeUser and deserializeUser do in PassportJS?

    serializeUser determines what user data (typically the user ID) is stored in the session after login. deserializeUser takes that stored identifier on subsequent requests and retrieves the full user object, attaching it to req.user. They are only needed for session-based auth.

Show the other 30 Security flashcards
  1. How is the passport-local strategy's verify callback expected to signal outcomes?

    The verify callback receives credentials and calls done(err, user, info): done(err) for an error, done(null, false, info) when authentication fails (bad credentials), and done(null, user) on success.

  2. How does PassportJS attach the authenticated user to a request?

    After a successful authentication, Passport populates req.user with the authenticated user object, making it available to downstream route handlers and middleware.

  3. What is Joi, and what is it used for in Node.js?

    Joi is a schema description and data validation library. You build a schema describing the shape and constraints of data (types, required fields, ranges, patterns) and validate incoming objects (like request bodies) against it, returning errors or validated values.

  4. Write a basic Joi schema that validates an object with a required string username (3-30 chars) and a required email.

    const schema = Joi.object({ username: Joi.string().min(3).max(30).required(), email: Joi.string().email().required() });

  5. What is the difference between schema.validate() and schema.validateAsync() in Joi?

    validate() runs synchronously and returns an object { value, error }. validateAsync() returns a Promise that resolves to the validated value or rejects with a ValidationError, and it is required when the schema uses async rules like external() references.

  6. In Joi, what does the abortEarly option control?

    By default abortEarly is true, so validation stops and reports only the first error. Setting { abortEarly: false } collects and returns all validation errors in the details array, which is useful for showing every form error at once.

  7. What is Validator.js, and how does it differ from Joi?

    Validator.js is a library of string validation and sanitization functions (e.g. isEmail, isURL, isUUID, normalizeEmail). It validates individual string values, whereas Joi validates entire structured objects against a declarative schema.

  8. Name five common Validator.js validation functions and what they check.

    isEmail (valid email format), isURL (valid URL), isUUID (valid UUID), isLength (string length within bounds), and isNumeric / isInt (numeric or integer strings). Validator.js operates on string inputs.

  9. What is the difference between validation and sanitization, and which does Validator.js support?

    Validation checks whether input meets rules and returns a boolean; sanitization transforms/cleans input into a safe canonical form. Validator.js supports both, with validators (isX) and sanitizers (e.g. trim, escape, normalizeEmail, toBoolean).

  10. What is Helmet in Express, and what does it do?

    Helmet is Express middleware that sets a collection of HTTP security response headers with safe defaults to help protect the app from common web vulnerabilities (XSS, clickjacking, MIME sniffing, etc.). You add it with app.use(helmet()).

  11. Which HTTP header does Helmet set to mitigate clickjacking, and what does it do?

    X-Frame-Options (set to SAMEORIGIN or DENY). It controls whether the page may be rendered inside a frame/iframe, preventing clickjacking by disallowing the site from being embedded by other origins.

  12. What is Content-Security-Policy (CSP), and how does Helmet relate to it?

    CSP is a header that whitelists the sources from which resources (scripts, styles, images) may load, mitigating XSS and injection. Helmet can set the Content-Security-Policy header (via helmet.contentSecurityPolicy()), though it must usually be configured explicitly for your app.

  13. What does the Strict-Transport-Security (HSTS) header do, and does Helmet set it?

    HSTS tells browsers to only communicate with the site over HTTPS for a specified max-age, preventing protocol-downgrade and SSL-stripping attacks. Helmet enables it by default via helmet.hsts().

  14. What is the purpose of the X-Content-Type-Options: nosniff header set by Helmet?

    It instructs the browser not to MIME-sniff (guess) a response's content type and to trust the declared Content-Type, preventing attacks where a file is interpreted as a different, executable type (e.g. treating an upload as a script).

  15. What is rate limiting, and why is it used?

    Rate limiting caps how many requests a client (usually identified by IP or API key) can make in a given time window. It protects against brute-force attacks, credential stuffing, denial-of-service, and API abuse, and helps ensure fair resource usage.

  16. In a fixed-window rate limiter, how do you express the allowed request rate?

    As a maximum count of requests per window: $$\text{rate} = \frac{\text{max requests}}{\text{window duration}}$$ e.g. $\frac{100\ \text{requests}}{15\ \text{minutes}}$. Once the counter reaches max within the window, further requests are rejected until the window resets.

  17. Compare the fixed-window and sliding-window rate-limiting algorithms.

    Fixed window counts requests in discrete time buckets and resets at each boundary, but allows bursts of up to 2x the limit around the boundary. Sliding window smooths this by weighting the previous window's count, giving a more accurate rolling rate at higher computational cost.

  18. Explain the token bucket rate-limiting algorithm.

    A bucket holds up to a capacity of tokens and refills at a fixed rate r tokens per second. Each request consumes one token; if the bucket is empty the request is throttled. It permits short bursts (up to bucket capacity) while enforcing an average rate over time.

  19. Which HTTP status code and headers typically signal a rate-limit rejection?

    HTTP 429 Too Many Requests. Servers often add a Retry-After header (seconds until retry) and informational headers like RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset.

  20. Why should a distributed/multi-instance API store rate-limit counters in a shared store like Redis?

    Because in-memory counters are per-process, so with multiple server instances each would track its own count, letting a client exceed the intended global limit. A shared store (e.g. Redis) gives a single authoritative counter across all instances.

  21. What is CORS, and what problem does it address?

    CORS (Cross-Origin Resource Sharing) is a browser security mechanism using HTTP headers that lets a server relax the Same-Origin Policy and explicitly permit web pages from other origins to access its resources. It controls cross-origin browser requests, not server-to-server calls.

  22. How is an 'origin' defined for the Same-Origin Policy and CORS?

    An origin is the tuple of scheme (protocol) + host + port. Two URLs share an origin only if all three match; any difference (e.g. http vs https, different subdomain, or different port) makes them cross-origin.

  23. Which response header is central to CORS, and what does it specify?

    Access-Control-Allow-Origin. It tells the browser which origin(s) are permitted to read the response, either a specific origin (e.g. https://app.example.com) or the wildcard * (which cannot be used with credentials).

  24. What is a CORS preflight request, and when is it triggered?

    A preflight is an automatic OPTIONS request the browser sends before the actual 'non-simple' request to ask permission. It is triggered by non-simple methods (PUT, DELETE, PATCH), custom headers, or certain Content-Types, and the server must answer with the appropriate Access-Control-Allow-* headers.

  25. What defines a CORS 'simple request' that does not require a preflight?

    A simple request uses GET, HEAD, or POST; includes only CORS-safelisted headers; and, for POST, uses a Content-Type of application/x-www-form-urlencoded, multipart/form-data, or text/plain. Such requests skip the preflight OPTIONS step.

  26. How do you allow credentials (cookies/authorization headers) in CORS, and what constraint applies?

    Set Access-Control-Allow-Credentials: true and have the client send credentials. The constraint: Access-Control-Allow-Origin must then be an explicit origin, not the wildcard *, or the browser will block the response.

  27. Which CORS response headers govern allowed methods and headers on preflight, plus preflight caching?

    Access-Control-Allow-Methods lists permitted HTTP methods, Access-Control-Allow-Headers lists permitted request headers, and Access-Control-Max-Age sets how long (seconds) the browser may cache the preflight result to avoid repeating it.

  28. Is CORS a defense against server-side attacks like CSRF or a substitute for authentication? Explain.

    No. CORS is enforced by the browser and only governs whether cross-origin JavaScript can read a response; it is not authentication or authorization and does not by itself stop CSRF. Non-browser clients ignore CORS entirely, so servers still need proper auth and CSRF protections.

  29. Compare Joi and Validator.js in terms of scope and typical use case.

    Joi validates whole structured objects against a declarative schema (great for validating request bodies/config). Validator.js provides individual string validators and sanitizers (great for checking or cleaning a single field like an email). They are often complementary.

  30. Contrast session-based authentication with stateless JWT authentication.

    Session-based auth stores session state server-side and gives the client a session ID cookie, requiring a server lookup per request but allowing easy revocation. JWT auth is stateless: the token itself carries signed claims, so no server store is needed, but tokens are harder to revoke before expiry.

NodeJS Security FAQ

What is in the NodeJS Security syllabus?

NodeJS Security is split into 3 chapters: Authentication, Data Validation and Common Security Practices. Together they contain 8 topics.

How many chapters are in NodeJS Security?

3 chapters, containing 8 topics. The largest chapter is Authentication, with 3 topics.

Are there flashcards for NodeJS Security?

Yes — a 50-card Security deck, printed in full in the flashcards section of this page and available in the Examius app with spaced repetition. The free plan covers one exam of your choice, including its flashcards; Examius Pro, a one-time purchase, unlocks every other exam and deck.