Why Does My Http://Localhost Cors Origin Not Work

Why does my http://localhost CORS origin not work?

Chrome does not support localhost for CORS requests (a bug opened in 2010, marked WontFix in 2014).

To get around this you can use a domain like localho.st (which points at 127.0.0.1 just like localhost) or start chrome with the --disable-web-security flag (assuming you're just testing).

Https not working for cors, but http://localhost is

The problem was with my server! Since I am using typescript I had to set up my package.json a certain way to build to heroku; However, for development purposes I changed my serve function from "node dist/index.js" to "nodemon dist/index.js" and rebuilt the project. I am using firebase for some other auth like functions that are in the frontend and thought because of that my backend was working fine but it was crashed. Turns out this was not a cors issue at all.

// ./Package.json
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"engines": {
"node": "14.x"
},
"scripts": {
"build-ts": "tsc",
"postinstall": "npm run build-ts",
"start": "npm run serve",
"serve": "node dist/index.js",
"watch-node": "nodemon dist/index.js",
"watch-ts": "tsc -w"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/connect-mongodb-session": "^2.4.2",
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/express-session": "^1.17.4",
"@types/node": "^17.0.21",
"nodemon": "^2.0.15",
"typescript": "^4.6.2"
},
"dependencies": {
"connect-mongodb-session": "^3.1.1",
"cors": "^2.8.5",
"dotenv": "^16.0.0",
"express": "^4.17.3",
"express-session": "^1.17.2",
"firebase-admin": "^10.0.2",
"mongoose": "^6.2.4"
}
}

CORS error on localhost, Is that a normal?

Yes, because CORS doesn't care about localhost in any specific way. Instead, the combination (!) of hostname and port is being used to differ between multiple parties.

Hence, for CORS, localhost:3000 is something completely different than localhost:8000, so, yes, this is normal.

CORS - localhost as allowed origin in production

I'm assuming you have

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://localhost

The risk is that any services running on a user's machine could effectively bypass the Same Origin Policy for your site.

So if you have a REST URL such as

https://example.com/User/GetUserDetails

A malicious or compromised service running on the user's computer could make that request via the user's browser and then grab details about the user, because their authentication cookie will be passed with the request.

Now, you could argue that a malicious service running on the user's computer could just grab the authentication cookie from their browser directly and then make the request itself. However, if the service has some flaws of its own (say XSS), this could allow another site to compromise the user via your REST service (evil.example.org --XSS-> localhost -CORS-> example.com/User/GetUserDetails).

Another scenario that could put you at risk if the user is running a local reverse proxy to access something. This would enable the target site to compromise the user through yours, should that target site be malicious or be compromised. This is because the user would be accessing the target site with a domain of localhost.

If you really need to do this I suggest you have a special developer account for your REST service that when accessed adds the Access-Control-Allow-Origin: https://localhost header to your requests only. That way, you are not putting other users at risk because you know you are only running the front-end server only at https://localhost so you cannot be compromised by your open CORS setting.

Another way may be to use something like noonewouldusethis2859282.localhost for your local copy of the front-end. Then you can safely add the Access-Control-Allow-Origin: https://noonewouldusethis2859282.localhost header because nobody else would use this and would be safe from CORS attacks.

Origin origin is not allowed by Access-Control-Allow-Origin

Since they are running on different ports, they are different JavaScript origin. It doesn't matter that they are on the same machine/hostname.

You need to enable CORS on the server (localhost:8080). Check out this site: http://enable-cors.org/

All you need to do is add an HTTP header to the server:

Access-Control-Allow-Origin: http://localhost:3000

Or, for simplicity:

Access-Control-Allow-Origin: *

Thought don't use "*" if your server is trying to set cookie and you use withCredentials = true

when responding to a credentialed request, server must specify a domain, and cannot use wild carding.

You can read more about withCredentials here

Why can't I connect to localhost server from localhost client (cors error)?

Any malicious site can take advantage of your cookies stored in the system called Cross-site request forgery

Any browser tries to prevent you from these attacks so they disable CORS.

Shorthand Fix [Not recommended] : There are many plugins out there you can use for your local testing that disables these checks on browser.

Proper Fix: Use an Express middleware to apply Access-Control-Allow-Origin: * in your header when response is returned back from the server.

Gist is that when browser sends the request to your server it will append Origin: http://localhost:3000 to the headers. Reacting to this request from browser, server should return a Access-Control-Allow-Origin header to specify which origins can access the server's resources.

You can be strict here to return Access-Control-Allow-Origin: http://localhost:4200 or open your gates by sending Access-Control-Allow-Origin: *.

Here is the quick code to have an express middleware:

const express = require('express');
const request = require('request');

const app = express();

app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});

app.get('/jokes/random', (req, res) => {
request(
{ url: 'https://joke-api-strict-cors.appspot.com/jokes/random' },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: err.message });
}

res.json(JSON.parse(body));
}
)
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));

Source: https://medium.com/@dtkatz/3-ways-to-fix-the-cors-error-and-how-access-control-allow-origin-works-d97d55946d9

P.S, this is a very good read for your understanding of CORS.

Chrome CORS error on request to localhost dev server from remote site

Original Answer

I finally found the answer, in this RFC about CORS-RFC1918 from a Chrome-team member. To sum it up, Chrome has implemented CORS-RFC1918, which prevents public network resources from requesting private-network resources - unless the public-network resource is secure (HTTPS) and the private-network resource provides appropriate (yet-undefined) CORS headers.

There's also a Chrome flag you can change to disable the new behavior for now:
chrome://flags/#block-insecure-private-network-requests

Disabling that flag does mean you're re-opening the security hole that Chrome's new behavior is meant to close.


Update 2021: A few months after I posted this question, the flag I referenced in my original answer was removed, and instead of disabling a security feature I was forced to solve the problem more satisfactorily by serving assets over HTTPS.

Update 2022: Chrome 98 is out, and it introduces support for Preflight requests. According to the announcement, failed requests are supposed to produce a warning and have no other effect, but in my case they are full errors that break my development sites. So I had to add middleware to teach webpack-dev-server how to serve preflight requests.

Private Network Access (formerly CORS-RFC1918) is a specification that forbids requests from less private network resources to more private network resources. Like HTTP to HTTPS, or a remote host to localhost.

The ultimate solution was to add a self-signed certificate and middleware which enabled requests from my remote dev server to my localhost webpack-dev-server for assets.

Generate certificates

cd path/to/.ssl
npx mkcert create-cert

Configure webpack-dev-server to use certificates and serve preflight requests

module.exports = {
//...
devServer: {
https: {
key: readFileSync("./.ssl/cert.key"),
cert: readFileSync("./.ssl/cert.crt"),
cacert: readFileSync("./.ssl/ca.crt"),
},

allowedHosts: ".example.dev", // should match host in origin below
setupMiddlewares(middlewares, devServer) {
// Serve OPTIONS requests
devServer.app.options('*', (req, res) => {
// Only serve if request has expected origin header
if (/^https:\/\/example\.dev$/.test(req.headers.origin)) {
res.set({
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Private-Network": "true",
// Using * results in error if request includes credentials
"Access-Control-Allow-Origin": req.headers.origin,
})

res.sendStatus(200)
}
}

return middlewares
}
}
}

Trust certificates

  1. Right click ca.crt in Windows Explorer and select Install Certificate
  2. Select Current User.
  3. Choose Place all certificates in the following store, then Browse..., and select Trusted Root Certification Authorities.
  4. Finish.

Firefox-specific instructions

Firefox doesn't respect your authoritah! by default. Configure it to do so with these steps:

  1. Type about:config into the address bar
  2. Search for security.enterprise_roots.enabled
  3. Toggle the setting to true

Cross origin requests are only supported for HTTP. error when loading a local file

My crystal ball says that you are loading the model using either file:// or C:/, which stays true to the error message as they are not http://

So you can either install a webserver in your local PC or upload the model somewhere else and use jsonp and change the url to http://example.com/path/to/model

Origin is defined in RFC-6454 as

   ...they have the same
scheme, host, and port. (See Section 4 for full details.)

So even though your file originates from the same host (localhost), but as long as the scheme is different (http / file), they are treated as different origin.



Related Topics



Leave a reply



Submit