How to Use a CORS Tester to Verify CORS Headers in Node.js
Use Node.js's built-in fetch API with mode: "cors" to trigger the internal corsCheck function, which validates Access-Control-Allow-Origin headers against the request origin before exposing the response.
Node.js implements the Fetch API through the bundled undici library, providing a robust way to test Cross-Origin Resource Sharing (CORS) configurations. By creating a cors tester script that sends requests with specific origins and modes, you can verify whether your server returns the correct CORS headers using the same validation logic that powers Node.js's internal fetch implementation.
Understanding CORS Validation in Node.js
When you make a fetch request with mode: "cors", Node.js invokes a strict validation routine defined in deps/undici/src/lib/web/fetch/util.js. The corsCheck function (lines 218–219) executes after receiving the HTTP response and performs two critical checks:
- Validates response-tainting: Ensures the request mode is
"cors"(or"websocket") to proceed with CORS validation. - Verifies
Access-Control-Allow-Origin: Compares the response header against the request'sOriginheader (lines 272–275). If the header is missing, malformed, or doesn't match, the fetch promise rejects with a CORS error.
If you use mode: "no-cors", the request bypasses these checks but restricts which HTTP methods and headers you can use (see deps/undici/src/lib/web/fetch/request.js, lines 456–461). Therefore, a proper cors tester must explicitly use mode: "cors" to trigger the full validation algorithm.
Setting Up a CORS Tester in Node.js
Creating a Test Server
First, create a local server that returns configurable CORS headers. This allows you to test various scenarios (matching origins, wildcards, or missing headers).
// server.js
import http from 'node:http';
const PORT = 8000;
http.createServer((req, res) => {
// Mirror the request origin or set a specific policy
const allowedOrigin = req.headers.origin || '*';
res.writeHead(200, {
'Access-Control-Allow-Origin': allowedOrigin,
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Content-Type': 'text/plain'
});
res.end('CORS-enabled response');
}).listen(PORT, () => {
console.log(`Test server running on http://localhost:${PORT}`);
});
Run this server with node server.js before executing your tests.
Writing the CORS Test Script
Use Node.js's global fetch (available in Node 18+) to send a request that triggers the internal corsCheck.
// cors-tester.js
const TARGET_URL = 'http://localhost:8000/';
const TEST_ORIGIN = 'https://example.com';
async function testCORS() {
try {
const response = await fetch(TARGET_URL, {
method: 'GET',
mode: 'cors', // Critical: triggers undici's CORS validation
headers: {
'Origin': TEST_ORIGIN // Mimics a cross-origin request
}
});
console.log('✅ CORS check passed');
console.log('Status:', response.status);
console.log('Body:', await response.text());
} catch (error) {
console.error('❌ CORS check failed:', error.message);
// This catches CORS errors when Access-Control-Allow-Origin mismatches
}
}
testCORS();
When the server returns Access-Control-Allow-Origin: https://example.com, the script outputs success. If the header is missing or contains a different origin, corsCheck rejects the promise with a network error, indicating your CORS policy blocks the request.
Leveraging Node.js Test Fixtures for CORS Testing
The Node.js repository includes a ready-made helper for generating CORS-compliant responses used in the Web Platform Tests (WPT) harness. Located at test/fixtures/wpt/common/custom-cors-response.js (lines 1–17), this fixture demonstrates the exact header structure required for valid CORS responses.
You can adapt this pattern for your own cors tester:
// Using the WPT fixture pattern
import http from 'node:http';
const PORT = 8000;
function createCORSResponse(body, origin) {
return {
headers: {
'Access-Control-Allow-Origin': origin,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
};
}
http.createServer((req, res) => {
const origin = req.headers.origin || '*';
const payload = { message: 'Valid CORS response', timestamp: Date.now() };
const { headers, body } = createCORSResponse(payload, origin);
res.writeHead(200, headers);
res.end(body);
}).listen(PORT);
This approach mirrors the official test suite, ensuring your cors tester validates headers exactly as Node.js does internally.
Key Source Files for CORS Testing
Understanding these specific files in the nodejs/node repository helps you debug CORS failures effectively:
deps/undici/src/lib/web/fetch/util.js: Contains thecorsCheckfunction (lines 218–219 and 272–275) that implements the core CORS validation algorithm according to the Fetch specification.deps/undici/src/lib/web/fetch/request.js: Defines how request modes (cors,no-cors,same-origin) influence header processing and method restrictions (lines 456–461).test/fixtures/wpt/common/custom-cors-response.js: Provides a reference implementation for constructing valid CORS responses used in Node.js's own test suite.
Summary
- Use
mode: "cors"in your fetch requests to trigger Node.js's internalcorsCheckvalidation. - The
corsCheckfunction indeps/undici/src/lib/web/fetch/util.jsvalidatesAccess-Control-Allow-Originheaders against the request origin. - Create a local test server that returns configurable CORS headers to simulate various cross-origin scenarios.
- Reference
custom-cors-response.jsfrom the Node.js test fixtures to ensure your test server follows the same patterns used in the official Web Platform Tests. - Catch promise rejections to identify when CORS policies block requests, indicating header mismatches or missing configurations.
Frequently Asked Questions
What is the corsCheck function in Node.js?
The corsCheck function is an internal utility in deps/undici/src/lib/web/fetch/util.js (lines 218–219) that validates whether a cross-origin response should be exposed to the calling code. It checks that the Access-Control-Allow-Origin header matches the request's Origin header and ensures the response isn't tainted by invalid CORS configurations. If validation fails, the function causes the fetch promise to reject with a network error before returning data to your application.
Why does mode: "cors" matter when testing CORS headers?
Setting mode: "cors" instructs Node.js's fetch implementation to run the full CORS validation algorithm defined in the Fetch specification. Without this mode (or when using mode: "no-cors"), the request bypasses the corsCheck validation and instead applies strict restrictions on usable methods and headers, as implemented in deps/undici/src/lib/web/fetch/request.js (lines 456–461). To test whether your server returns valid CORS headers, you must use mode: "cors" to trigger the actual validation logic.
Where can I find the CORS test fixtures in the Node.js repository?
The official CORS test fixtures are located at test/fixtures/wpt/common/custom-cors-response.js in the Node.js repository. This file contains helper functions used by the Web Platform Tests harness to generate responses with properly formatted Access-Control-Allow-Origin headers. You can reuse these patterns in your own cors tester scripts to ensure your test server produces standards-compliant CORS responses.
How does Node.js handle CORS errors during fetch requests?
When the corsCheck function detects a CORS violation—such as a missing Access-Control-Allow-Origin header or an origin mismatch—it rejects the fetch promise with a network error before exposing any response data to your JavaScript code. This behavior occurs in deps/undici/src/lib/web/fetch/util.js (lines 272–275) and matches the security model implemented in web browsers, ensuring that malicious cross-origin responses cannot be inspected by the requesting application.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →