-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The current proxy handling breakes various common use cases #62
Comments
Can't proxy implementers resolve this by simply tagging any proxied hosts with the proper address partition via a header containing the |
That should work on HTTP(S) proxies (although I don't know the situation of CONNECT requests), but does not cover SOCKS5 proxies that do not involve headers in any way (some of the applications mentioned above are actually SOCKS5-only). At the same time, Chrome is shipping PNA in 94 without this and already breaking sites (and apparently they do not even know that this 11-month old CSP directive exists, as seen in that issue), so I'm a bit concerned. |
This is the last discussion I remember on the subject. Your concern seems to be almost the opposite of the concern in that discussion, however the solution doesn't seem to be different. The browser just needs a way of knowing what partition the destination host is in, meaning either the browser has the IP (directly or by performing the name resolution itself) or the proxy provides the network partition somehow (e.g. via One additional thought is that the browser could expose a proxy configuration option for default handling of an unknown partition. I could imagine something like this:
Obviously that would be a user-agent customization rather than something written in the spec, but does that sound like what you're asking for? |
Guess I'll be talking to the Chromium guys (who are not currently
responding) then.
There should be:
* An option to treat a proxy as public or private, which should not only be
a group policy, which is not available in Home editions of Windows
* Some kind of API for extensions to do the same
BTW, if memory serves me right, making a proxied request to a HTTP (not
HTTPS) site is almost the same as treating the proxy endpoint as the actual
site, only with extra headers and a different `Host`.
Since some CSRF attacks are doable with only GET requests, how will that be
treated? preflights?
Justin Schuh ***@***.***> 于 2021年10月16日周六 01:12写道:
… This is the last discussion I remember
<#41 (comment)>
on the subject. Your concern seems to be almost the opposite of the concern
in that discussion, however the solution doesn't seem to be different. The
browser just needs a way of knowing what partition the destination host is
in, meaning either the browser has the IP (directly or by performing the
name resolution itself) or the proxy provides the network partition somehow
(e.g. via treat-as-public-address).
One additional thought is that the browser could expose a proxy
configuration option for default handling of an unknown partition. I could
imagine something like this:
1. Default to partition of proxy's address
2. Default to private
3. Default to public
Obviously that would be a user-agent customization rather than something
written in the spec, but does that sound like what you're asking for?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#62 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKRK2BJOOSHUYY7QYXL5RDUHBOGXANCNFSM5GCETKXA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Another consideration is user experience. Before this, setting up a proxy is a zero/one-click operation: the application automatically set up the proxy configuration in Windows using Windows APIs, and the user can just launch Chrome and get started. |
Thanks for the feedback on this blind spot, and for examples of affected proxy software! This is very helpful. I am curious to understand why such software only proxies part of some websites. Is it common for websites residing inside the GFW to rely on resources from CDNs outside? This brings me to a second question: how hard is it to fix your setup by changing the rules according to which some websites are proxied and others are not? it is true that SOCKS proxies would not be able to insert CSP headers into responses, as they do not necessarily have visibility into those - in case of HTTPS, this goes from complicated to impossible.
This should be doable, though it is true that it involves futzing around with settings in a way that was not necessary before.
For Chrome, it seems |
Sites inside GFW usually does not use resources from other CDNs, however sites outside China might load itself just fine (not inpacted by GFW) while rely on CDNs that is not available inside GFW. In that case the site itself is not proxied while its resources are. At the same time, sites inside China usually performs badly if accessed abroad. GFW is a multi-level architecture and individual/regional ISPs might have extra rules (for example, China Mobile users in some regions have more difficulty access GitHub than other major ISPs), and CDNs like jsDelivrm which actually has servers in China, and is used by large sites, is also sometime affected. The current situation described above makes it necessary to use complex rules (both PAC and rules inside proxy app) to decide which site to proxy or not. The local part of these proxy application usually forwards local (private) traffic directly out as this is the most desirable outcome, making the PNA protection unavailable unless they return that header conditionally. However, some user might choose to relay these private traffic to a remote server, acting like a enterprise VPN. Due to the number of people using these proxy services and applications, not being able to automate this can quickly turn into a support nigtmare as they do not always automatically update like their Chrome is. Current SolutionsApplications providing HTTP proxies should be updated to inject that CSP header, while SOCKS5-only proxies should be put behind softwares such as BTW, is that CSP rule already supported in Chromium? After all, HTTP sites are no longer that common now, but can be extremely confusing to normal users that does not understand technologies very well. |
Thanks for the explanation! That makes a lot more sense.
I believe that putting the SOCKS5-only proxy behind an HTTP proxy should allow a However, now that I think of it some more, in the absence of a mechanism for treating proxies as belonging to another address space, this would prevent proxied websites from embedding any proxied resources (considered local). Indeed, the header only works to drop privileges on a document. PNA blocks fetches before a request is ever made, so resources have no opportunity to set a header indicating they really should be treated as public. This means that the CSP header alone cannot be a solution. What we really need is a setting to control how proxies are handled, or to exempt proxies entirely. |
Yeah, even if the header works, there is no opportunity for the proxy to
indicate that in the first place since no request is ever made.
I suppose that we are not able to ever fully protect users behind a proxy,
as the name resulotion is sometimes also delegated to a remote server and
the proxy client (i.e., proxy software running on the user’s device) never
knows if it is requesting a private address, for example
192.168.133.7.traefik.me.
Titouan Rigoudy ***@***.***>于2021年10月21日 周四00:12写道:
… Thanks for the explanation! That makes a lot more sense.
is that CSP rule already supported in Chromium?
Content-Security-Policy: treat-as-public-address works in Chromium. The
hypothetical treat-as-private-address does not.
Applications providing HTTP proxies should be updated to inject that CSP
header, while SOCKS5-only proxies should be put behind softwares such as
Privoxy.
I believe that putting the SOCKS5-only proxy behind an HTTP proxy should
allow a CSP: treat-as-public-address header to be injected indeed. That
would improve the user's security by preventing proxied websites from
poking at the local network.
However, now that I think of it some more, in the absence of a mechanism
for treating proxies as belonging to another address space, this would
prevent proxied websites from embedding any proxied resources (considered
local). Indeed, the header only works to drop privileges on a document. PNA
blocks fetches before a request is ever made, so resources have no
opportunity to set a header indicating they really should be treated as
public.
This means that the CSP header alone cannot be a solution. What we really
need is a setting to control how proxies are handled, or to exempt proxies
entirely.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#62 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKRK2GKKRLUDZEXMCB5P6TUH3TAHANCNFSM5GCETKXA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Exactly.
That may be true! That said, even in the case of traefik.me, xip.io, sslip.io etc., the proxy does know the target IP address once it connects the socket at the very least. |
It is possible to indicate the resolved address by extending the proxy
headers, but it might be too late.
If memory serves me right, Chromium sends ClientHello after it sees the
HTTP proxy's headers, but for obfuscation reasons, the underlying proxy
tunnel is not created until CH (or the first actual data block after
CONNECT header) is sent from the browser, and the proxy response header is
not sent until the actual server responds.
That means that by the time Chrome sees the CONNECT proxy headers, address
is not known unless we do DNS lookups on the client side, which has privacy
and stability issues due to DNS pollution.
Titouan Rigoudy ***@***.***> 于 2021年10月21日周四 00:54写道:
… Yeah, even if the header works, there is no opportunity for the proxy to
indicate that in the first place since no request is ever made.
Exactly.
I suppose that we are not able to ever fully protect users behind a proxy,
as the name resulotion is sometimes also delegated to a remote server and
the proxy client (i.e., proxy software running on the user’s device) never
knows if it is requesting a private address, for example
192.168.133.7.traefik.me.
That may be true! That said, even in the case of traefik.me, xip.io,
sslip.io etc., the proxy does know the target IP address once it connects
the socket at the very least.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#62 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKRK2CCEGZEMGGFHTE6YYTUH3X3HANCNFSM5GCETKXA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Interesting. I guess this behavior depends on the proxy? Or is it specified? Also, does this not introduce a circular dependency?
Anyway, it is interesting to me that we can do something better for CONNECT than for simple HTTP proxied requests. Indeed, in the simple HTTP case, there is no way for the browser to get information about the target endpoint before sending the request - since the only response the browser gets is the proxied response, once the target endpoint has received the request and replied. This defeats the purpose of PNA - sending the request alone is enough for CSRF. OTOH, in the CONNECT case, the proxy returns a response to the browser after establishing a TCP connection to the target endpoint. This is the point in time at which PNA checks are applied in the non-proxied case. The browser could then act on the information returned by the proxy (via CSP, which seems ill-suited, or rather some other |
It works like this:
This behavior is application dependent, but the proxy application always sends its protocol header along with the first bits of actual application data to reduce the chance of being detected and save RTT. |
Ah, I see. Without this, a timing attack can reveal proxy users, where TCP connections are opened, then left hanging for a bit before any bits are sent on the wire? |
They do not even need a timing "attack", as ordinary HTTPS traffic almost
always has a fixed number of RTT in the handshake phase, anything extra can
be used to detect proxy users based on traffic.
Titouan Rigoudy ***@***.***> 于2021年10月21日周四 下午9:51写道:
… Ah, I see. Without this, a timing attack can reveal proxy users, where TCP
connections are opened, then left hanging for a bit before any bits are
sent on the wire?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#62 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKRK2G7DUM2ITKHSB7O3MLUIALE3ANCNFSM5GCETKXA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Makes sense. |
FYI, I've disabled this behavior in Chrome 98: https://crrev.com/c/3320317 fixed https://crbug.com/1253239. Now the spec needs updating to reflect this state of affairs. |
As per https://crbug.com/1253239, the standards prevents HTTP sites from accessing any resource (be it HTTP or HTTPS) through a local (or private) proxy, which is a very common use case in China and other regions where people use proxies (that are alternatives of traditional VPNs) running locally (listening on 127.0.0.1 or 0.0.0.0) to access some parts of the internet. Some users use extensions such as
SwitchyOmega
, but more users do not use any extensions or PAC rules, instead they route all traffic to the proxy and let the proxy application decide if it needs to send the request to a remote server or simple forward it locally. In this case, HTTP sites are totally broken.The current standard also breaks debugging a public HTTP site with Fiddler, but this particular use case should be fine since the user is expected to be a developer.
The problem is that the site itself might not be proxied because of extensions or PAC rules ("public"), while its resources (e.g. served from Google CDN, which is proxied) essentially become "private".
For examples, check
Clash
,V2Ray/V2Fly
, andShadowsocks
.The text was updated successfully, but these errors were encountered: