-
-
Notifications
You must be signed in to change notification settings - Fork 205
fix: remove RTCPeerConnection exhaustion (FILL500) #5451
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
Conversation
6d6f08b to
15f3e5a
Compare
15f3e5a to
78d74de
Compare
|
Rebased. |
This partially reverts 750721c (#3098). Not completely though: the `<iframe>` thing is still there, and I have not removed it yet for the sake of being conservative. The most important point of this change is to prepare ourselves for the removal of the `IsolateSandboxedIframes` Chromium feature. It has been enabled by default, and is to be removed soon-ish: https://issues.chromium.org/issues/362246896. The feature makes the RTCPeerConnection exhaustion hack not work anymore, because an attacker can create a sandboxed `<iframe>`, and, as the feature name implies, process-isolated, thus have a separate RTCPeerConnection 500 pool. Earlier we simply un-enabled this Chromium feature in 50bcd88 (#4351), but when it's removed, we will not be able to. We could hold off on upgrading Electron then, but let's not. To answer "Why haven't we done this before?": probably because the 500 hack was the first thing that proved to work, both on Electron and in Android. But in Android apparently one can't control the WebRTC IP handling policy, so this approach is not available on Android. Another thing is, of course, the fact that this speeds up the process of launching an app. And in general this approach seems more thorough to me. It also provides another exfiltration security layer (a dummy proxy) against regular HTTP requests as well, i.e. it guards even against CSP bypass. This uses the same approach that we took in the Tauri version: #4852. On top of that, the 500 limit itself is not something that is set in stone and should be relied on. To check that this still works, follow the instructions in https://github.com/webxdc/webxdc-test/pull/40/files.
78d74de to
a69f8d2
Compare
|
Rebased, and adjusted comments a little. I also re-tested this with the instructions above. All works well. |
nicodh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed by reading & testing
I tested this with following results:
I can confirm that without setWebRTCIPHandlingPolicy('disable_non_proxied_udp')
the requests to the STUN server can reach the server which is not the case if the policy is set.
The dns prefetch is also blocked except, if the lines
rawApp.commandLine.appendSwitch('host-resolver-rules', hostRules)
rawApp.commandLine.appendSwitch('host-rules', hostRules)
are removed
Concerning the dummy proxy approach: is that taken from a specific source or just an own idea? I see how it works but I can't really say if this approach is valid.
Some documentation in the code would help here:
Is it related to disable_non_proxied_udp or "just another exfiltration security layer" as described?
How can it be tested that it's needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is that taken from a specific source or just an own idea?
An own idea basically. I don't recall seeing it anywhere else.
I see how it works but I can't really say if this approach is valid.
Sorry, I might have forgotten to link to the spec, or just assumed that it's obvious where to find it (which it is not). See my new suggestion comment.
Is it related to disable_non_proxied_udp or "just another exfiltration security layer" as described?
As I commented "However, weirdly, this alone seems to disable WebRTC, even without setting a proxy". I expect that setting a proxy is required to make disable_non_proxied_udp work as we want, but apparently just disable_non_proxied_udp is enough.
How can it be tested that it's needed?
I have submitted MRs about this:
This partially reverts 750721c
(#3098).
Not completely though: the
<iframe>thing is still there,and I have not removed it yet for the sake of being conservative.
The most important point of this change is to prepare ourselves
for the removal of the
IsolateSandboxedIframesChromium feature.It has been enabled by default, and the switch
is to be removed soon-ish:
https://issues.chromium.org/issues/362246896.
The feature makes the RTCPeerConnection exhaustion hack
not work anymore, because an attacker can create
a sandboxed
<iframe>, and, as the feature name implies,the iframe would be process-isolated,
thus have a separate RTCPeerConnection 500 pool.
Earlier we simply un-enabled this Chromium feature in
50bcd88
(#4351),
but when it's removed, we will not be able to.
We could hold off on upgrading Electron then, but let's not.
To answer "Why haven't we done this before?":
probably because the 500 hack was the first thing
that proved to work, both on Electron and in Android.
But in Android apparently one can't control
the WebRTC IP handling policy, so this approach
is not available on Android.
Another thing is, of course, the fact that this speeds up
the process of launching an app.
And in general this approach seems more thorough to me.
It also provides another exfiltration security layer (a dummy proxy)
against regular HTTP requests as well,
i.e. it guards even against CSP bypass.
This uses the same approach that we took in the Tauri version:
#4852.
On top of that, the 500 limit itself is not something
that is set in stone and should be relied on.
To check that this still works, follow the instructions in
https://github.com/webxdc/webxdc-test/pull/40/files.
TODO:
.xdc, i.e. the app that hasinternet_access. So this depends on Maps with own session #5455 (unless we are willing to break maps XD).Edit: or actually, we could just have a separate
sesfor the maps.xdcwhere we don't set the proxy 🤷♀️.