Course contentsShow
← Node.js
Lesson 1807 of 1,98016. Security Hardening and Threat MitigationFree lesson

Cross-Origin Resource Sharing Best Practices

Restrict CORS policies to specific, trusted origins to prevent unauthorized cross-domain data access.

Cross-Origin Resource Sharing Best Practices

In this lesson, you will learn how to secure your Node.js API by implementing strict origin-based access controls to prevent unauthorized data exposure.

When a web browser makes a request to your API from a different domain, the browser enforces the Same-Origin Policy. CORS is the mechanism that allows you to relax this policy securely. However, the most common security mistake developers make is using a wildcard (Access-Control-Allow-Origin: *). While convenient during development, a wildcard allows any malicious website to make authenticated requests to your resources, potentially exfiltrating sensitive user data.

Implementing an Origin Whitelist

The gold standard for CORS security is to maintain a strict "allowlist" of trusted origins. Instead of returning a static wildcard, your middleware should dynamically verify the Origin header of the incoming request against your pre-defined list of trusted domains.

If the Origin matches an entry in your list, you reflect that specific origin back in the Access-Control-Allow-Origin header. If it does not match, you omit the header entirely, causing the browser to block the request.

const whitelist = ['https://app.trusted-client.com', 'https://api.internal-service.com'];

const corsOptions = {
  origin: (origin, callback) => {
    // Allow requests with no origin (like mobile apps or curl)
    if (!origin) return callback(null, true);

    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  optionsSuccessStatus: 200 // Legacy browser support
};

Strategic Considerations

  1. Avoid Wildcards in Production: Never use * if your application requires authentication (like cookies or Authorization headers).
  2. Handle Preflights: Browsers send an OPTIONS request (preflight) to check your policy before the actual data request. Ensure your configuration correctly responds to these requests without leaking internal structure.
  3. Dynamic Evaluation: By using a whitelist, you ensure that you are in total control of which domains can interact with your Node.js application, effectively neutralizing unauthorized cross-domain data access.

Key Takeaway: Always replace wildcard CORS policies with a strictly enforced whitelist of trusted domains to ensure only authorized origins can interact with your sensitive API endpoints.