WICG / direct-sockets

Direct Sockets API for the web platform
Other
337 stars 14 forks source link

Bypassing CORS would be very useful #19

Closed dieulot closed 1 year ago

dieulot commented 4 years ago

Threat

Attackers may use the API to by-pass third parties' CORS policies.

Mitigation

We could forbid the API from being used for TCP with the well known HTTPS port, whenever the destination host supports CORS.

A lot of services (Reddit and Twitter for instance) are available over the web yet have a CORS policy that forbids third-party websites from accessing them. That is so because they don’t want malicious scripts on third-party sites accessing their data.

Third-party clients for such services are in demand. The only way to do one at the moment is with a native app, which are plentiful for the aforementioned Reddit and Twitter.

I’ve personally made a third-party client for jeuxvideo.com’s forums in the past (biggest forums in Europe, and my app was eventually responsible for 10% of the messages posted there), which was loved both by users and the staff as it resulted in much more engagement. It was a web app though, with a back-end proxying the site, and it was delicate to do as the developers had to make special exceptions in their infrastructure specifically for my service when they had a lot of other priorities, resulting in my service often rendered unavailable.

Making a third-party client as a web app makes it available on all platforms, without requiring a download, while requiring less effort to implement it than on just one platform natively, and there are more developers available for the web platforms that can create such solutions. It’s an absolutely wonderful thing.

As long as the user is made aware clearly of what allowing Raw Sockets on an HTTPS service entails, I believe this should be made possible as it would unlock a ton of useful and very accessible services, without more harm done than is possible with non-HTTPS services accessed through Raw Sockets.

ewilligers commented 4 years ago

The explainer and spec could leave this at the user agent's discretion. Without speaking for other browser vendors, my expectation is that Chrome would implement the mitigation, i.e. it would forbid the API from being used for TCP with the well known HTTPS port, whenever the destination host supports CORS.

The mitigations are respectful to a range of parties:

osmarks commented 4 years ago

What does "supports CORS" mean? By default, the same-origin policy is enforced and a website is not allowed to be connected to by other websites' code (excluding GET/POST requests which don't let you see the result because of course). They have to actually opt into CORS to allow cross-origin fetching beyond this.

HKalbasi commented 4 years ago

What is risk of CORS connection when cookies and other browser specific won't be send? A malicious web site can't see your twitter data with TCP connections (Like an android native app can't) So why forbidding the API from using for HTTPS? What is difference between HTTPS and other TCP protocols?

osmarks commented 4 years ago

What is risk of CORS connection when cookies and other browser specific won't be send? A malicious web site can't see your twitter data with TCP connections (Like an android native app can't)

Some stuff, I think primarily intranet-type applications, grant access based on IP (or don't do auth but are behind a firewall).

What is difference between HTTPS and other TCP protocols?

That is a problem too - this can't actually detect HTTP(S) except by port, which is inaccurate. While maybe the browser could inspect the TCP stream to look for HTTP-request-looking things, that would be complex, flaky, slow, and probably insecure - plus applications could just do HTTPS and avoid said inspection.

HKalbasi commented 4 years ago

Some stuff, I think primarily intranet-type applications, grant access based on IP (or don't do auth but are behind a firewall).

This is the problem with every protocol, not only HTTP(S). Am I right? So there is no difference between HTTP(S) and other protocols that imply banning HTTP(S).

osmarks commented 4 years ago

This is the problem with every protocol, not only HTTP(S). Am I right? So there is no difference between HTTP(S) and other protocols that imply banning HTTP(S).

I suppose the idea is that this shouldn't be able to bypass existing cross-origin-request related restrictions, but those mostly make sense in the context of cookies and such being shared, which doesn't apply here. This API does seem to break much of the security model, with the main restriction being that you just need to have the user click "yes" on something (the documentation here has no mitigations for DNS rebinding attacks which don't affect private networks).

dead-claudia commented 2 years ago

I have massive security concerns with this, particularly if fully automated: malicious sites could easily use visiting browsers to spam servers with exploits while evading detection, not unlike a botnet. And this could be easily cloaked by either wrapping it in a news aggregator or something similar or by compromising and using a reasonably popular site.

Edit: Part of https://github.com/WICG/direct-sockets/issues/45 would resolve my concerns here.

jimmywarting commented 2 years ago

I have for such a long time wished that it was possible to make a raw request to xyz that didn't send the user's credentials. this CORS restriction dose not close the gap of what a browser and a native app is able to accomplish.

I have also personally built cors proxies (to bypass things) before. it's such a wasteful transmission to have to make a server having to make all the request on the users behalf and have to pay the server bills for it. then the server becomes the bottleneck and the resource needs to be downloaded twice wasting bandwidth, once by the server and once by the client.
It creates such a unnecessery rate limit on the server sometimes cuz it's spamming the hell out of some other service.

one good usecase for allowing any website to make raw request could be to fetch og:meta tags and do different things with it.

<meta property="og:title" content="How to Become an SEO Expert (8 Steps)" />
<meta property="og:description" content="Get from SEO newbie to SEO pro in 8 simple steps." />
<meta property="og:image" content="https://ahrefs.com/blog/wp-content/uploads/2019/12/fb-how-to-become-an-seo-expert.png" />

1000 of websites have useful og meta data and 99% of this probably don't have CORS enabled... so it's left to the server to do the job. Some of this could even be geo ip based on languages and/or be blacklisted/whitelisted by countries at where you host your CORS proxy. Another reason for allowing raw request cold be for p2p web push delivery without the need of any server (as the endpoint should be CORS enabled but they aren't by some services, only firefox dose this) https://github.com/w3c/push-api/issues/303


I might been the reason why such many service from Cors proxies isn't longer working... The list was shared by many other blog/articles and was based on my list.

the possibility to make a request on the users behalf instead would be very very useful. given that they can do the same thing as mobile application with just some permission dialogs... Meaning raw request without forwarding any stored credentials, cookies or some cache logic that browser dose for you automatically.

It would be nice to no longer have to resort to having to use any CORS proxies that are limited to the country at where the hosting provider allows you to host your CORS proxy

I would be fine if i could ask the user for permission to make request to https://example.com if that meant that i could start hosting static content only without the need of some server side logic.


the web has so huge potential for doing so much more things if this where enabled. botnet, spamming services and evading detection can all be resolved with a proper permission model by the browser & the user


Web3.0 is mostly about decentralization without the need of a single point of failure. We need to embrace this. Skipping the need for a proxy server also means less user tracking. Hosting provider can collect a lot of information about a user even if I don't track anything about the user myself, it will know the ip of the user and sometime read plain insecure http request as many services are masked with https to http, skipping the need of ssl certificate.

if you had the option to choose between

  1. allow https://enable-cors.appengine.com make a request to xyz on your behalf, exposing your ip adress to both google's appengine and the cors proxy server in itself to build up a user profile on you. the cors proxy will probably be x-forwarding your ip address to the other service as well and also be able to read the payload and the response before it is handed to the user and wasting bandwidth time. there is also a chance that it will do some geo location lookup to change language or block the request entierly
  2. or simply just make a direct connection to xyz without any MIT

what would you prefer?

rektide commented 1 year ago

This issue will be resolved with #60, via this change, yay!

GrapeGreen commented 1 year ago

Closing this since #60 is indeed the solution.