Back to course

Cross-Origin Resource Sharing (CORS)

TL;DR: Only allow the origins that actually need access to your API. Never use a wildcard on authenticated endpoints. CORS is your browser-level access control list.

your-app.comtrusted originevil-site.com blockedyour APIchecks origin headerallowedrejectedresponsewith CORS headers

CORS is a browser mechanism that controls which domains can make requests to your API. By default, browsers block cross-origin requests. CORS lets you selectively open that up for trusted origins.

The common mistake is opening it up too much. Setting Access-Control-Allow-Origin: * tells the browser that any website on the internet can call your API. On a public read-only API, that might be intentional. On anything with authentication or sensitive data, it’s a serious problem.

A malicious site could make requests to your API on behalf of a logged-in user, and since the origin check passes, the browser won’t stop it. This is the foundation of CSRF-style attacks.

Be specific about which origins you allow. Be specific about which HTTP methods you accept. If your API only serves GET and POST requests, there’s no reason to allow DELETE.

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', 'your-safe-origin.com');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

If you need to allow multiple origins, maintain an allowlist and check the incoming Origin header against it rather than reflecting it back blindly.

Further reading: MDN Web Docs on CORS