From 78201a3a5c483bed31f4ae38b7fd41b9bb8b178a Mon Sep 17 00:00:00 2001 From: Mahmoud Hamdi Date: Sun, 29 Mar 2026 04:24:41 +0200 Subject: [PATCH] fix: set Vary: Origin header when origin callback rejects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the origin callback returns false (rejecting the request origin), the middleware now sets the Vary: Origin response header before passing control to next(). This prevents HTTP caches from incorrectly reusing a response generated for one origin when handling requests from a different origin. Per the Fetch specification (https://fetch.spec.whatwg.org/#cors-protocol-and-http-caches): if a server's response depends on the Origin request header, Vary: Origin must be set — even when the origin is not allowed — to ensure correct cache behavior. Previously, when a dynamic origin function rejected a request, no headers were set at all. A cache could then store this response and serve it to a subsequent CORS request from an allowed origin, which would incorrectly lack the Access-Control-Allow-Origin header. Fixes #330 --- lib/index.js | 3 +++ test/test.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/index.js b/lib/index.js index ad899ca..e52329b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -218,6 +218,9 @@ if (originCallback) { originCallback(req.headers.origin, function (err2, origin) { if (err2 || !origin) { + // Set Vary: Origin even when the origin is not allowed, + // since the response depends on the Origin request header + vary(res, 'Origin'); next(err2); } else { corsOptions.origin = origin; diff --git a/test/test.js b/test/test.js index 34ddb41..1125929 100644 --- a/test/test.js +++ b/test/test.js @@ -360,6 +360,7 @@ var util = require('util') assert.equal(res.getHeader('Access-Control-Allow-Headers'), undefined) assert.equal(res.getHeader('Access-Control-Allow-Credentials'), undefined) assert.equal(res.getHeader('Access-Control-Max-Age'), undefined) + assert.equal(res.getHeader('Vary'), 'Origin') done(); }; @@ -393,6 +394,7 @@ var util = require('util') assert.equal(res.getHeader('Access-Control-Allow-Headers'), undefined) assert.equal(res.getHeader('Access-Control-Allow-Credentials'), undefined) assert.equal(res.getHeader('Access-Control-Max-Age'), undefined) + assert.equal(res.getHeader('Vary'), 'Origin') done(); };