NodeJS - CORS middleware `origin` undefined
Asked Answered
D

3

33

I have an app using the cors npm package as middleware. I have it set up like this:

  if(process.env.NODE_ENV === 'production') {
    var whitelist = ['http://mywebsite.com', 'https://mywebsite.com']
    var corsOptions = {
      origin: (origin, callback) => {
          var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
          console.log('ORIGIN: ', origin);  // => undefined
          callback(originIsWhitelisted ? null : 'Bad Request', originIsWhitelisted)
      },
      credentials:true
    }
    app.use(cors(corsOptions));
  }

The origin parameter in my corsOptions is undefined. Why is this and how can I fix it?

Definite answered 3/3, 2017 at 23:0 Comment(1)
github.com/expressjs/cors/issues/71Elongation
A
30

If you do not want to block REST tools or server-to-server requests, add a !origin check in the origin function like so:

var corsOptions = {
  origin: function (origin, callback) {
    if (!origin || whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}
Altostratus answered 16/3, 2019 at 9:53 Comment(3)
As its undefined if same origin, wouldn't it make sens to check for that instead rather than just a falsey value? origin === undefinedApodal
There is a security issue when using if (!origin) in production: many of the pentest scripts don't set origin, so their requests will pass this CORS test. My production server was getting hit with thousands of pentest requests, until I stripped the if(!origin) test.Amboina
@Amboina and how did you manage to go around that? Because if you just remove the if(!origin) requests from the same origin will be rejected.Holmann
R
25

This happens when you load your page in the same origin that you are making API calls to. The browser doesn't set the "Origin" header unless the API call's domain is different from the one where the page is being served.

This is further explained here https://github.com/expressjs/cors/issues/113

If you make your API call using the browser console, from within a different website, you'll see that the browser sets the Origin header, and thus it will not be undefined when read by express.

You can account for this by using

if (whitelist.indexOf(origin) !== -1 || !origin) 
Rickirickie answered 1/9, 2020 at 9:3 Comment(2)
As a complete non-export on CORS, I thought the whole point of having a whitelist was to prevent ineligible origins?Pritchard
Unfortunately the linked github issue has been deleted. Can someone explain why allowing an undefined origin is not a security issue? This seems a bit unintuitive.Energize
R
1

use is a method to configure the middleware .You must apply the corsoptions in the route only. This is what i'm see based on the documentation. Not tested it yet. Hope it'll help yaa.

var whitelist = ['http://example1.com', 'http://example2.com']
var corsOptions = {
  origin: function (origin, callback) {
    var originIsWhitelisted = whitelist.indexOf(origin) !== -1
    callback(originIsWhitelisted ? null : 'Bad Request', originIsWhitelisted)
  }
}

app.get('/products/:id', cors(corsOptions), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a whitelisted domain.'})
})
Rewarding answered 3/3, 2017 at 23:27 Comment(1)
The whole point of middleware is to apply a given operation to lots of routes. You certainly can use CORS at the middleware level if you want. Or, you can apply it to only a certain route. You do not have to use it with app.get(). It can be used with app.use() just fine.Palla

© 2022 - 2024 — McMap. All rights reserved.