From dc7ad95270bdcbce9cf03c48ac8eef30c669f96d Mon Sep 17 00:00:00 2001 From: Tom Brouwer Date: Wed, 23 Feb 2022 08:58:51 +0100 Subject: [PATCH] fix: 'isRequestOriginAllowed' returns mixed results when regex is used (#152) The 'isRequestOriginAllowed' function returned random results for global regexes, since the .test function was used, and the output of this function depends on previous invocations of the function. By resetting the 'lastIndex', every invocation of the function should now return the same result. This also updates the corresponding test to use a global regex, and do the same validation twice, in order to check consistency fixes #151 Co-authored-by: Tom Brouwer --- index.js | 1 + test/cors.test.js | 35 ++++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index 59bf7a4..248a6c0 100644 --- a/index.js +++ b/index.js @@ -210,6 +210,7 @@ function isRequestOriginAllowed (reqOrigin, allowedOrigin) { } else if (typeof allowedOrigin === 'string') { return reqOrigin === allowedOrigin } else if (allowedOrigin instanceof RegExp) { + allowedOrigin.lastIndex = 0 return allowedOrigin.test(reqOrigin) } else { return !!allowedOrigin diff --git a/test/cors.test.js b/test/cors.test.js index 73e6249..0c52eab 100644 --- a/test/cors.test.js +++ b/test/cors.test.js @@ -631,29 +631,34 @@ test('Allow only request from multiple specific origin', t => { }) test('Allow only request from a specific origin using regex', t => { - t.plan(4) + t.plan(8) const fastify = Fastify() - fastify.register(cors, { origin: /^(example|other)\.com/ }) + fastify.register(cors, { origin: /(example|other)\.com/gi }) fastify.get('/', (req, reply) => { reply.send('ok') }) - fastify.inject({ - method: 'GET', - url: '/', - headers: { origin: 'example.com' } - }, (err, res) => { - t.error(err) - delete res.headers.date - t.equal(res.statusCode, 200) - t.equal(res.payload, 'ok') - t.match(res.headers, { - 'access-control-allow-origin': 'example.com', - vary: 'Origin' + // .test was previously used, which caused 2 consecutive requests to return + // different results with global (e.g. /g) regexes. Therefore, check this + // twice to check consistency + for (let i = 0; i < 2; i++) { + fastify.inject({ + method: 'GET', + url: '/', + headers: { origin: 'https://www.example.com/' } + }, (err, res) => { + t.error(err) + delete res.headers.date + t.equal(res.statusCode, 200) + t.equal(res.payload, 'ok') + t.match(res.headers, { + 'access-control-allow-origin': 'https://www.example.com/', + vary: 'Origin' + }) }) - }) + } }) test('Disable preflight', t => {