From my understanding, using the CORS module will remove the Access-Control-Allow-Origin
header from the resource, causing XmlHttp requests to fail from the browser.
However, does this prevent Http requests from a CURL, or other native applications/web-servers (ie. a request written and run via PHP) from successfully retrieving data from that resource?
The CORS mechanism supports secure cross-origin requests and data transfers between browsers and servers. Modern browsers use CORS in APIs such as XMLHttpRequest or Fetch to mitigate the risks of cross-origin HTTP requests.
To allow any site to make CORS requests without using the * wildcard (for example, to enable credentials), your server must read the value of the request's Origin header and use that value to set Access-Control-Allow-Origin , and must also set a Vary: Origin header to indicate that some headers are being set ...
Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served. A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos.
CORS is an important security feature that is designed to prevent JavaScript clients from accessing data from other domains without authorization. Modern web browsers implement CORS to block cross-domain JavaScript requests by default.
However, does this prevent Http requests from a CURL, or other native applications/web-servers (ie. a request written and run via PHP) from successfully retrieving data from that resource?
No, CORS config won’t prevent non-browser stuff from successfully retrieving your resources.
The same-origin policy is enforced only by browsers. It’s not enforced by servers. (And CORS is a way to relax the same-origin policy.) It’s not the case that if there’s some lack of any CORS details in a request, servers somehow block requests, or refuse to send responses.
Instead when you configure CORS support on a server, all that the server does differently is just to send the Access-Control-Allow-Origin
header and other CORS response headers.
The way the protocol works is, regardless of what CORS configuration you make on the server side, all clients—even browsers—continue to get responses from the server as they normally would. But the difference is, curl
or other native apps or backend server-side programming environments such as PHP will not prevent your client code from accessing the response if it doesn’t include the Access-Control-Allow-Origin
response header. But browsers will.
Specifically, even if you see an error in your browser devtools that a cross-origin request from your frontend JavaScript code failed, you’ll still be able to see the response in browser devtools.
But just because your browser can see the response doesn’t mean the browser will expose it to your frontend JavaScript code. Browsers only expose responses from cross-origin requests to frontend code running at a particular origin if the server the request went to opts-in to allowing the request, by responding with an Access-Control-Allow-Origin
header allowing that origin.
But browsers are the only clients which do that. Browsers are the only clients that implement the same-origin policy and the CORS protocol. curl
or other native applications or HTTP client requests made server-side runtimes such as PHP don’t implement the CORS protocol, so you can’t block requests from them by doing any CORS configuration on the server side.
So If you want to block requests to a resource from non-browser clients, you need to do it using something other than CORS configuration.
I could successfully prevent a server like Postman to send me a request in my CORS-protected API route by throwing an error if the domain is not in my whitelist and by setting the origin of request dynamically.
Here is my postman in which I set all headers like Access-Control-Allow-Origin:
The request was blocked from Postman server and returning a 500 internal Server Error
after the error is thrown in my live server as you can see here:
Using Express/Node.js with cors
version 2.8.5, my code looks like this:
const whitelistDomains = [
'http://awesomesite123.com',
'https://localhost:3000',
];
const corsOptions = {
origin: function (origin, callback) {
if (whitelistDomains.includes(origin)) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
},
optionsSuccessStatus: 200, // For legacy browser support
methods: ['GET', 'PUT', 'POST', 'DELETE'],
}
app.use(cors(corsOptions));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With