http-server icon indicating copy to clipboard operation
http-server copied to clipboard

Mirror domain in Access-Control-Allow-Origin header

Open matthias-ccri opened this issue 2 years ago • 12 comments

Browsers sometimes reject wildcard origins (*) in Access-Control-Allow-Origin headers, so a common practice is for the server to simply mirror the domain back, instead of sending *. Can http-server support this?

Steps to reproduce the issue, if applicable. Include the actual command and output and/or stack trace.

npx http-server --cors

What did you expect to happen?

Expected http-server to send the header based on the request's Origin header: Access-Control-Allow-Origin: localhost:8088

What actually happened?

http-server sent this header: Access-Control-Allow-Origin: *

and the browser rejected it:

Access to XMLHttpRequest at 'http://127.0.0.1:8082/sample.json' from origin 'http://localhost:8088' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

If the issue is a feature request, what is the motivation / use case for it?

Tell us about your environment

  • exact http-server version: latest
  • Node version: n/a
  • Platform: n/a

Other information (related issues, suggestions for a fix, etc):

matthias-ccri avatar Sep 16 '21 01:09 matthias-ccri

Do you know what browsers do this and/or why?

thornjad avatar Sep 16 '21 16:09 thornjad

I'm using Chrome 93.0.4577.63, but apparently this behavior has existed since Chrome 49 and FF 45.

  • MDN has a note on the wildcard: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
  • Spec mentions "non-wildcard" requests: https://fetch.spec.whatwg.org/#access-control-allow-headers-response-header
  • Discussion here: https://github.com/whatwg/fetch/issues/251

Only an issue with credentialed requests. Here is a stat saying 30% of XHRs are crossOrigin using withCredentials.

matthias-ccri avatar Sep 16 '21 18:09 matthias-ccri

This seems like a good addition, I don't have time to work on it right now but would love a PR from anyone!

thornjad avatar Oct 26 '21 14:10 thornjad

This issue has been inactive for 180 days

github-actions[bot] avatar Apr 25 '22 12:04 github-actions[bot]

The PR (https://github.com/http-party/http-server/pull/760) is waiting to be merged. Can someone merge it?

matthias-ccri avatar Apr 28 '22 23:04 matthias-ccri

I like this as a fix as it would fix my CORS issues. I currently run two servers with SSL Client Cert verification enabled. When server1 makes a request to server2 it fails because of the wildcard.

Since the --cors option hard codes the access-control-allow-origin to * it wont work with firefox, as firefox currently (correctly) follows the fetch spec: https://fetch.spec.whatwg.org/#cors-protocol-and-credentials Currently, Chrome and Edge do not: https://bugs.chromium.org/p/chromium/issues/detail?id=775438

As the fetch spec I linked says:

A request’s credentials mode is not necessarily observable on the server; only when credentials exist for a request can it be observed by virtue of the credentials being included. Note that even so, a CORS-preflight request never includes credentials. The server developer therefore needs to decide whether or not responses "tainted" with credentials can be shared. And also needs to decide if requests necessitating a CORS-preflight request can include credentials. Generally speaking, both sharing responses and allowing requests with credentials is rather unsafe, and extreme care has to be taken to avoid the confused deputy problem. To share responses with credentials, the Access-Control-Allow-Origin and Access-Control-Allow-Credentials headers are important....

My concern with always mirroring the origin server is that in production this may introduce security issues.

Would it not be 'safer' to have an option to specifically set access-control-allow-origin to a specific URL? ie access-control-allow-origin: https://my.server.tld"

SkepticNerdGuy avatar Apr 29 '22 01:04 SkepticNerdGuy

@SkepticNerdGuy this library has never been production-ready in terms of CORS, because the Access-Control-Allow-Origin header is not configurable and it only returns Access-Control-Allow-Origin: *. I've only ever used this as a development tool.

Feel free to open a separate issue for supporting configurability of the Access-Control-Allow-Origin response header.

matthias-ccri avatar Apr 29 '22 05:04 matthias-ccri

@matthias-ccri Your right in regard to CORS not being production ready. I will make that separate issue, thank you for the suggestion, I am pretty new at this and a novice at best.

Though, this project is refereed to as " powerful enough for production usage"

http-server is a simple, zero-configuration command-line static HTTP server. It is powerful enough for production usage, but it's simple and hackable enough to be used for testing, local development and learning.

Your feature is great for dev-testing for sure, just afraid for the poor sap that enables it in production. I suppose my only suggestion is that the it be mentioned to not enable it in production, and that it's a dev testing tool as it basically circumvents browser 's ability to enforce the "fetch" standard to protect from possible exploit.

Again thanks for the fast response.

SkepticNerdGuy avatar Apr 29 '22 23:04 SkepticNerdGuy

This issue has been inactive for 180 days

github-actions[bot] avatar Oct 28 '22 12:10 github-actions[bot]

Bump. This is waiting to be merged.

matthias-ccri avatar Oct 28 '22 15:10 matthias-ccri

To conclude the above discussion, the suggestion of this issue (to mirror the Origin instead of sending a wildcard *) is not a change to the security or purpose of the library; in fact it aligns with it. This library has always been a development tool not fit or advertised for production usage. That's why the cors feature has always returned *.

If there are suggestions to support configuring a whitelist of origins, that would require either a breaking change to the --cors flag or the introduction of a new flag or configuration method. This is not that.

My suggestion in this ticket is not a breaking change to the --cors flag. It's an improvement and it has no downsides. Mirroring the origin instead of using a wildcard is 1) equivalent and 2) better (because it supports credentialed requests).

So this ticket seems like a good thing to do. @thornjad is there any opposition to it?

matthias-ccri avatar May 08 '23 19:05 matthias-ccri

@thornjad any opposition to this PR?

matthias-ccri avatar Jul 11 '23 04:07 matthias-ccri