Restricting CORS Origin to a Whitelist: Why and How?

Modern web applications often rely on APIs hosted on different domains — this is called cross-origin communication. While useful, this opens up potential attack vectors, especially if not properly controlled. That’s where CORS (Cross-Origin Resource Sharing) comes in.

What is CORS?

CORS is a browser security feature that controls how and whether frontend JavaScript running on one origin (e.g., https://app.example.com) can make requests to a different origin (e.g., https://api.example.com).

To permit this, the server must explicitly allow such access by setting CORS headers, particularly:

Access-Control-Allow-Origin: https://app.example.com

But what happens if you set:

Access-Control-Allow-Origin: *

This allows any domain to access your API — including malicious ones. This is rarely a good idea unless you’re serving public, non-sensitive content.

The Right Way: Restrict to a Whitelist

Why Whitelist Specific Origins?

  • Prevents data theft by rogue JavaScript from untrusted websites
  • Protects APIs that serve sensitive information (auth tokens, user data, etc.)
  • Mitigates risks from phishing sites attempting to access user sessions

Important Security Tips

  • Never use Access-Control-Allow-Origin: * with cookies or authorization headers
  • Always validate the Origin header on the server, not the client
  • Log CORS rejections for debugging and security audits
  • Consider using a dynamic origin check if the list is large or changes often

In Summary

CORS is a powerful but dangerous gate. While it enables useful cross-origin interactions, it must be tightly controlled to avoid exposing your users and systems to cross-site attacks.

Whitelist only what you trust. Log what you reject. Audit your CORS rules regularly.

How to Implement CORS Whitelisting (Server-Side Examples)

Example in Node.js / Express


const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];

app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }
  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');
  next();
});
  

Example in Python / Flask


from flask import Flask, request
from flask_cors import CORS

app = Flask(__name__)
allowed_origins = ['https://app.example.com', 'https://admin.example.com']

def custom_cors(origin):
    return origin in allowed_origins

CORS(app, origins=custom_cors)
  

Example in .NET (ASP.NET Core)


var allowedOrigins = new[] { "https://app.example.com", "https://admin.example.com" };

builder.Services.AddCors(options =>
{
    options.AddPolicy("RestrictedPolicy", policy =>
    {
        policy.WithOrigins(allowedOrigins)
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});

Anuj holds professional certifications in Google Cloud, AWS as well as certifications in Docker and App Performance Tools such as New Relic. He specializes in Cloud Security, Data Encryption and Container Technologies.

Initial Consultation

Anuj Varma – who has written posts on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.