From 274ed30bdc4c06596fe061f3b8bc871f284f7a2f Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Thu, 23 Apr 2026 19:45:34 +0800 Subject: [PATCH] Fix: throw error when credentials=true with origin='*' According to CORS specification, using wildcard '*' in Access-Control-Allow-Origin header is forbidden when Access-Control-Allow-Credentials is set to true. This fix adds validation that throws an error when both options are set, following the fetch spec: https://fetch.spec.whatwg.org/#cors-protocol-and-credentials Fixes expressjs/cors#333 --- lib/index.js | 9 +++++++++ test/test.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lib/index.js b/lib/index.js index ad899ca..0043fe0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -70,6 +70,13 @@ return headers; } + function validateCredentialsAndOrigin(options) { + if (options.credentials === true && options.origin === '*') { + throw new Error('Cross-origin requests are not allowed when credentials are set to true with origin: "*". ' + + 'See https://fetch.spec.whatwg.org/#cors-protocol-and-credentials'); + } + } + function configureMethods(options) { var methods = options.methods; if (methods.join) { @@ -160,6 +167,8 @@ var headers = [], method = req.method && req.method.toUpperCase && req.method.toUpperCase(); + validateCredentialsAndOrigin(options); + if (method === 'OPTIONS') { // preflight headers.push(configureOrigin(options, req)); diff --git a/test/test.js b/test/test.js index 34ddb41..d17f423 100644 --- a/test/test.js +++ b/test/test.js @@ -729,3 +729,38 @@ FakeResponse.prototype.setHeader = function setHeader (name, value) { var key = name.toLowerCase() this._headers[key] = value } + +describe('credentials with origin "*"', function () { + it('throws an error when origin is "*" and credentials is true', function (done) { + var req = fakeRequest('GET'); + var res = fakeResponse(); + var next = function (err) { + if (err && err.message.indexOf('credentials') !== -1 && err.message.indexOf('origin') !== -1) { + done(); + } else { + done(new Error('Expected error about credentials and origin, got: ' + (err ? err.message : 'no error'))); + } + }; + + assert.throws(function () { + cors({ origin: '*', credentials: true })(req, res, next); + }, /Cross-origin requests are not allowed when credentials are set to true with origin/); + done(); + }); + + it('allows origin "*" when credentials is false', function (done) { + var cb = after(1, done); + var req = fakeRequest('GET'); + var res = new FakeResponse(); + + res.on('finish', function () { + assert.equal(res.getHeader('Access-Control-Allow-Origin'), '*'); + assert.equal(res.getHeader('Access-Control-Allow-Credentials'), undefined); + cb(); + }); + + cors({ origin: '*', credentials: false })(req, res, function (err) { + cb(err || new Error('should not be called')); + }); + }); +});