Issue
TLDR: I read that the "origin" header can be set manually for requests,
and that CORS policy are only securing browser requests.
how can I make my app securely send data to allowed origins ?
I am making a personal server with express that fetches and deliver data from multiple sources to multiple targets, including a static website
On this api I use a few express routes & socket.io, but to keep it simple i am only going to talk about express routes.
I already implemented CORS policy by adding an Access-Control-Allow-Origin
header in the response, but I could read that CORS are not enabled for program or server requests (like curl
)
So I added a little logic to check if the "origin" header was in my whitelist, like this :
// cors middleware
module.exports = function corsCheck (req, res, next) {
const origin = req.header("origin")
const host = req.header("host")
// list of allowed origins
const allowed = [
"https://gui3.github.io"
]
res.header({
// "Content-Type": "application/json",
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept"
})
if (allowed.includes(origin)) { // here is the cross origin logic
res.status(200)
res.header("Access-Control-Allow-Origin", origin)
next()
}
else {
console.log("403 forbidden request")
res.status(403)
res.json({
allowed: false,
error: "403 forbidden access"
})
}
}
and in app.js
// ... express stuff
// send data
app.get("/data", corsCheck, (req, res) => {
res.send(data)
})
// more express stuff
This is working fine for now, but I read here
that you can specify a handmade origin at least in curl.
My question is :
How can I be sure of the true origin of a request ? and how can I make my api open to requests that only come from my static website ?
PS : I though of some kind of password in a custom header, but since my site is static, I don’t know how to have a secure password in an open source static website.
Solution
It looks like you will need more then CORS for your Problem.
Try to implement an authentication system with A JSON Web Token (https://jwt.io/)(https://www.youtube.com/watch?v=7Q17ubqLfaM) or Sessions (https://www.npmjs.com/package/express-session), because Headers can be set manually and can be unreliable.
If you have the capabilities, also Try to look into HTTPS, it’s more secure, this Thread has more Information on that: Enabling HTTPS on express.js
And be sure to have a look at the cors module (https://www.npmjs.com/package/cors)! It can be configured for your needs. Just look into the documentation
Have a nice day!