Fix: throw error when credentials=true with origin='*' - #413
jiafeimao0p wants to merge 1 commit into
Conversation
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#333
kilisamemarisaaa
left a comment
There was a problem hiding this comment.
I found a runtime error-propagation issue in the proposed validation.
validateCredentialsAndOrigin() throws from cors() after the options callback has been entered. With the supported dynamic-options form, the callback can run asynchronously, so the Express middleware stack has already returned and cannot catch that throw. A minimal reproduction on Node 24 with this PR is:
const express = require('express')
const request = require('supertest')
const cors = require('./')
const app = express()
app.use(cors((req, cb) => process.nextTick(() => cb(null, {
origin: '*',
credentials: true
}))))
app.get('/', (req, res) => res.send('ok'))
process.once('uncaughtException', err => console.log('UNCAUGHT', err.message))
request(app).get('/')It prints UNCAUGHT Cross-origin requests are not allowed ... and the request never reaches an Express error handler. Static options happen to be synchronous and are caught by Express, which makes this path easy to miss. Please validate before the asynchronous boundary or propagate the validation failure through next(err)/the options callback, and add a regression test using an asynchronous options callback plus an error handler.
Summary
According to the CORS specification, using wildcard
*inAccess-Control-Allow-Originheader is forbidden whenAccess-Control-Allow-Credentialsis set totrue.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
Problem
Currently, the cors middleware allows setting
credentials: truewithorigin: '*', which violates the CORS standard and causes browsers to reject the request.Solution
Added a
validateCredentialsAndOrigin()function that throws an error when bothcredentialsistrueandoriginis'*'.Changes
lib/index.js: AddedvalidateCredentialsAndOrigin()function and call it in the cors middlewaretest/test.js: Added test cases for the new validationTesting
Added test cases:
credentials=trueandorigin='*'origin='*'works normally whencredentials=falseFixes #333