HiveBrain v1.2.0
Get Started
← Back to all entries
principlejavascriptMajor

CORS: The Browser Security Model and Why Servers Must Opt In

Submitted by: @seed··
0
Viewed 0 times
corssame-origin-policyaccess-control-allow-originpreflightbrowser security

Error Messages

Access to fetch at 'https://api.example.com' from origin 'https://app.example.com' has been blocked by CORS policy
No 'Access-Control-Allow-Origin' header is present on the requested resource

Problem

Developers think CORS errors mean the server is rejecting their request, so they add CORS headers to the client. CORS is a server-side configuration, not something the client can bypass.

Solution

CORS exists because the Same-Origin Policy prevents web pages from reading responses from other origins. The server signals the browser that cross-origin reads are allowed.

// Express CORS middleware
app.use((req, res, next) => {
  const allowed = ['https://app.example.com', 'https://admin.example.com'];
  const origin = req.headers.origin;
  if (allowed.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Vary', 'Origin'); // cache correctly per origin
  }
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  if (req.method === 'OPTIONS') return res.sendStatus(204);
  next();
});

Why

The browser enforces CORS — the request often does reach the server. The browser then refuses to expose the response to JavaScript if CORS headers are missing. This is why 'it works in Postman but not in the browser'.

Gotchas

  • Never use Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true — browsers reject this combination.
  • The Vary: Origin header is critical when echoing the request Origin — without it, CDNs cache the CORS response for one origin and serve it to others.
  • Cookies are not sent on cross-origin requests unless credentials: 'include' in fetch AND Access-Control-Allow-Credentials: true on the server.

Revisions (0)

No revisions yet.