Web Security
Beginner
2 min read
CORS Pitfalls, Null Origin, and Private Network Access
Example
// Node.js / Express: robust CORS with allowlist and null-origin protection
const express = require('express');
const app = express();
const ALLOWED_ORIGINS = new Set([
'https://app.example.com',
'https://admin.example.com',
// Never add 'null' here!
]);
function corsMiddleware(req, res, next) {
const origin = req.headers.origin;
// Only set CORS headers if origin is in the allowlist
// and not the literal string 'null'
if (origin && origin !== 'null' && ALLOWED_ORIGINS.has(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Vary', 'Origin'); // critical: tell caches this varies per origin
}
if (req.method === 'OPTIONS') {
// Preflight response
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');
res.setHeader('Access-Control-Max-Age', '86400');
// Private Network Access support for internal services
if (req.headers['access-control-request-private-network']) {
res.setHeader('Access-Control-Allow-Private-Network', 'true');
}
return res.sendStatus(204);
}
next();
}
app.use(corsMiddleware);
app.get('/api/data', (req, res) => res.json({ status: 'ok' }));
app.listen(3000);
Related Resources
Web Security Reference
Complete tag & property list
Web Security How-To Guides
Step-by-step practical guides
Web Security Exercises
Practice what you've learned
More in Web Security