What is CORS? Cross-Origin Resource Sharing Explained

Share

TL;DR

CORS (Cross-Origin Resource Sharing) is a browser security feature that controls which websites can make requests to your API. By default, browsers block requests from different domains. CORS headers tell browsers which origins are allowed. Never use Access-Control-Allow-Origin: * for APIs that handle authentication or sensitive data. Specify exact allowed origins instead.

The Simple Explanation

Your app is at app.yoursite.com. Your API is at api.yoursite.com. When JavaScript on your app tries to fetch data from the API, the browser says "wait, these are different origins." The browser blocks the request unless the API says it's okay.

CORS is the mechanism where your API tells the browser "yes, this origin is allowed to make requests to me."

What Is an Origin?

An origin is a combination of:

  • Protocol (http vs https)
  • Domain (example.com)
  • Port (3000, 8080, etc.)

These are all different origins:

CORS Headers

The server responds with headers that tell the browser what's allowed:

CORS response headers

Access-Control-Allow-Origin: https://app.yoursite.com Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Allow-Credentials: true

Configuring CORS Properly

Security mistake: Using Access-Control-Allow-Origin: * allows ANY website to make requests to your API. If you use cookies or return sensitive data, this is dangerous.

For APIs with Authentication

Node.js Express example

const cors = require('cors');

app.use(cors({ origin: 'https://app.yoursite.com', 'https://admin.yoursite.com', credentials: true, methods: 'GET', 'POST', 'PUT', 'DELETE' }));

For Public APIs (No Auth)

Truly public API

app.use(cors({ origin: '*', methods: 'GET' // Only allow reading, no writing }));

Common CORS Issues

  • Development vs Production: Different URLs need different origins configured
  • Preflight failures: Server must handle OPTIONS requests
  • Credentials with wildcard: Can't use * origin with credentials: true

Why is Access-Control-Allow-Origin: * dangerous?

Using * allows any website to make requests to your API. If your API uses cookies or returns sensitive data, malicious sites can access it. Only use * for truly public APIs that don't require authentication. For authenticated endpoints, specify exact allowed origins.

Why do I get CORS errors in development but not production?

In development, your frontend (localhost:3000) and backend (localhost:8000) are different origins. In production, they might be on the same domain. You need to configure CORS to allow your development origin, or use a proxy. Most frameworks like Next.js and Vite can proxy API requests to avoid CORS during development.

What is a preflight request?

Before making certain cross-origin requests (like PUT, DELETE, or requests with custom headers), browsers send an OPTIONS request to check if the actual request is allowed. This is the preflight. Your server must respond with appropriate CORS headers to allow the real request to proceed.

Check Your CORS

Scan your API for CORS misconfigurations.

Start Free Scan
Security Glossary

What is CORS? Cross-Origin Resource Sharing Explained