logoalt Hacker News

muvlontoday at 6:05 AM9 repliesview on HN

Even TFA seemingly doesn't understand CORS. Or at least misreprents it grossly:

> The webserver listening in on localhost:19421 should implement a REST API and set a Access-Control-Allow-Origin header with the value https://zoom.us. This will ensure that only Javascript running on the zoom.us domain can talk to the localhost webserver.

No, that does not do that. JavaScript from any other website can still talk to localhost:19421 just the same. CORS doesn't restrict anything, it loosens the default set of restrictions (ignoring preflight requests for now and assuming we're talking just about "safe" Methods). That Access-Control-Allow-Origin header just allows JavaScript running on zoom.us to read the responses when it queries localhost:19421. The requests happen in any case, and you must ensure in your backend that they don't cause any adverse effects.


Replies

stymaartoday at 11:30 AM

I don't understand why this is the most upvoted comment. OP is right, and you are wrong.

> The requests happen in any case, and you must ensure in your backend that they don't cause any adverse effects.

GET requests will be sent, but they are supposed to be idempotent so if your server is implemented in a sensible way, it cannot cause any adverse effect, and reading the response is all that matters for GET requests.

For non-idempotent requests however (the only ones that are supposed to be able to have side effects), a preflight OPTION request will be sent in cross-origin context instead of sending the request itself. And unless the right headers are set in the OPTION response, the request won't be sent at all.

show 6 replies
Lerctoday at 7:07 AM

I don't think you can even say CORS does that.

The degree to which CORS is poorly understood (I have read numerous (often contradictory) documentation and I don't really understand it.) means that you can't rely on it being implemented properly by an unknown party,

If a protocol reaches this level of widespread confusion, I think all bets are off. Even if one end of a system performs correctly, who's to say that the other will. If people adapt their code until it works with another implementation, were they mistaken, or the other end?

show 3 replies
Sophiratoday at 10:59 AM

My understanding was that "preventing otherwise disallowed HTTP requests" was the entire point of the preflight OPTIONS request, and that CORS will do nothing if the request would otherwise be allowed.

For example, a POST request with a Content-Type of "text/json" would not be allowed to be sent to third-party hosts without an OPTIONS preflight, but one with a Content-Type of "multipart/form-data" would be allowed and wouldn't be stopped by CORS at all, even to third-party hosts.

(And, of course, if your endpoint just assumes JSON without strictly checking the Content-Type, then congratulations, you've just allowed any website to POST to you, with no user action required.)

show 1 reply
SahAssartoday at 8:05 AM

> assuming we're talking just about "safe" Methods

That's a pretty big assumption. Any decent webdev should not let GET/HEAD/OPTIONS modify state (joining a meeting is changing state) and additionally PUT/DELETE should also be idempotent.

POST with JSON (or other non-form formats) api's should also have it's content-type header checked (text/plain forms can send a JSON body but the content-type will be text/plain). PUT/PATCH/DELETE and POST with a non-form content-type (application/x-www-form-urlencoded, multipart/form-data, or text/plain) will trigger a preflight so that CORS is properly checked before the actual request reaches the server.

show 1 reply
bwblabstoday at 8:33 AM

Another quote from the article:

> Further, native apps can generate a unique self-signed certificate.

Just creating a certificate will not work, unless it's installed as root CA certificates in all browser trust-stores on the machine. And if the private key of the root CA is not secured correctly, one could MitM any websites. So at least you want it name constrained (https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1....), but at least in Chrome until 2023 (v112) that did not work on root CA's (https://alexsci.com/blog/name-non-constraint/), so you had to add an intermediate CA and add the constrain there. Of course, you should also just throw away the key of the root CA.

I will admit I once added basic constrains in some project with a local root CA (2020-2022), but 'incorrectly' to the root CA, and did not test it in all browsers.

xg15today at 10:27 AM

> (ignoring preflight requests for now and assuming we're talking just about "safe" Methods)

You can't ignore those because they constitute the bulk of CORS' security model.

Yes, you're technically right that CORS cannot prevent other websites from making any request to your server - this would be impossible, since the browser somehow has to get the CORS headers in the first place.

However what CORS absolutely lets you do is prevent requests to particular endpoints - and you can then design your API in such a way that the dangerous actions are only available behind those endpoints and thus make it safe.

I.e. what's missing in the TFA quote is that the server must also change the endpoint from GET to POST (in addition to setting the CORS headers) and remove the GET endpoint. Other websites would still be able to send a GET or a preflight OPTIONS request, but they wouldn't be able to send the actual POST request.

As such, Zoom's workaround had two problems: They didn't set any CORS headers, which prompted the browsers to only allow "safe", i.e. GET requests - and then put an unsafe action behind the endpoint, therefore violating the "safe" assumption. Moral of the story: Don't put actions that do something else than returning a result behind a GET request.

show 1 reply
z3t4today at 10:30 AM

Importantly it only prevents clients that actually cares about the cors headers. Like ohh I'm from hacker.org and the http headers says it only allows zoom.us ohh nooooo. Like it's just a http header! Now if you use a mainstream browsers and you accidentally visits hacker.org in a iframe at some shady site - then the cors header will prevent your browser from accessing it.

bazoom42today at 11:55 AM

“Can still talk to, but cant read the response” is a bit too simplied. You can’t post a json payload for example, which is how a JavaScript client would usually talk to a backend. You can only post using form data encoding, since this is already possible using a plain html form without any JavaScript. Anything beyound that, like json/xml payloads or methods other than post and get are blocked by default.

paulddrapertoday at 4:15 PM

>> This will ensure that only Javascript running on the zoom.us domain can talk to the localhost webserver.

> No, that does not do that.

It restricts non-zoom.us domains to CORS-safe operations.

Which sometimes includes making the request, sometimes includes reading the response content or headers.