Skip to content
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

[Critical] IP leaking through webrtc #117

Open
ghost opened this issue Jan 29, 2018 · 40 comments

Comments

Projects
None yet
8 participants
@ghost
Copy link

commented Jan 29, 2018

  1. Open iPhone : ip 1.1.1.1
  2. Connect to VPN : ip 2.2.2.2
  3. Check web etc leaks : no leak (2.2.2.2)
  4. Open onion browser 2.0.1 : ip 3.3.3.3
  5. Check web rtc leak : leaking 1.1.1.1
@tladesignz

This comment has been minimized.

Copy link
Collaborator

commented Jan 29, 2018

Most probably same as #112

@tladesignz

This comment has been minimized.

Copy link
Collaborator

commented Jan 29, 2018

We're trying to push an update, but Apple...

@ebelinski

This comment has been minimized.

Copy link

commented Jan 29, 2018

@tladesignz Did you request an expedited review?

@tladesignz

This comment has been minimized.

Copy link
Collaborator

commented Feb 4, 2018

Thanks for the hint with the expedited review. We finally got it through after working out all the issues with Apple they suddenly found. They are sometimes quite cryptic, when it comes to explaining the issue...

Can you please check again and confirm if we got this fixed?

@ghost

This comment has been minimized.

Copy link
Author

commented Feb 5, 2018

@tladesignz

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2018

@n8fr8

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2018

@ghost are you saying that Onion Browser 2 leaks outside of the VPN? The WebRTC leak happens even if the VPN is on?

@mtigas

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2018

(Update -- April 4 2019. After being fixed on iOS 12, this is apparently happening again on iOS 12.2.)

OK, this was not the same as #112.

Quick notes from some research here.

From the thread of the tweet that tladesignz linked, this started in iOS 11.

It also affects Red Onion and Brave (brave/browser-ios#1148).

My original guess was that we could plug this with the same content-security-policy injection from Onion Browser 1. OB1 disables websockets and 'connect' stuff by by default, it is only optional in Endless/OB2. That was a mistake and will be fixed, but that has no affect on WebRTC.

So this probably affects ALL Onion Browser on iOS 11.X.

Further, there used to be a mitigation in Brave brave/browser-ios@f22e37b , but it appears to have been removed brave/browser-ios@893af7e , and my own testing (adding the trapInstanceMethod bits from that file into https://github.com/mtigas/OnionBrowser/blob/2.X/Endless/Resources/injected.js which should add it to every page) also don't seem to have any affect in the iOS 11.2 simulator. (I'm investigating this further, since simply making RTCPeerConnection calls no-op should mitigate this.)

I'm also investigating whether iOS 11.3 beta changes things, because none of my devices using the 11.3 beta leak IP over WebRTC, even in Safari. https://twitter.com/mtigas/status/961665006344589312

@n8fr8

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2018

This can also be mitigated by disabling Javascript entirely? Is that feature available still in iOS 11 / Endless codebase?

@mtigas

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2018

@n8fr8
yes:
Settings -> Host Settings -> Default Settings
Content policy: "Strict (no JavaScript, video, etc.)"
simulator screen shot - iphone 8 - 2018-02-08 at 15 06 55

mtigas added a commit that referenced this issue Feb 8, 2018

@mtigas mtigas self-assigned this Feb 8, 2018

@mtigas mtigas added the bug label Feb 8, 2018

@n8fr8

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2018

I would tweet that this can be immediately fixed by disable javascript by default for all sites, and show that screenshot: https://github.com/mtigas/OnionBrowser/issues/117#issuecomment-364232729

Perhaps JS should be off by default, and people can selectively enable by host?

@n8fr8

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2018

img_0975

confirmed disable javascript blocks webrtc leak from happening

@MarkCallow

This comment has been minimized.

Copy link

commented Sep 27, 2018

Just tested iOS 12. I changed Content Policy to Permissive then connected to https://browserleaks.com/webrtc. Below is the output. No IP addresses are detected but RTCPeerConnection and RTCDataChannel are both checked. Not sure if this means the issue is resolved or not.

img_0161

@tladesignz

This comment has been minimized.

Copy link
Collaborator

commented Apr 3, 2019

iOS 12.2 - WebRTC leaks IP address with default configuration:

  • Allow WebRTC: No
  • Content Policy: No XHR/WebSocket/Video connections

Simulator Screen Shot - iOS 12 2 @ iPad Pro - 2019-04-03 at 10 04 01

When Content Policy is changed to "Strict (no JavaScript, video etc.)", leak becomes impossible.

@MarkCallow

This comment has been minimized.

Copy link

commented Apr 3, 2019

@tladesignz, the "alt" title on the image you posted suggests it came from the iOS Simulator rather than a real iOS device. If this indeed was from the simulator, please test with a real device.

iOS 12.1 is fine. I just tested. But in view of this issue, I am holding off updating to 12.2.

@tladesignz

This comment has been minimized.

Copy link
Collaborator

commented Apr 4, 2019

@MarkCallow Thanks for your input!

Just tested with a real device running iOS 12.2. Same issue.

Also tested on IOS 11.4 in the simulator. It leaks. But you're right: that could be due to the underlying MacOS 10.14.4.

Unfortunately, I don't have a device around which runs iOS 11.0 - 12.1.

So, thanks again for your input, I really appreciate it!

@mtigas: We need a security warning on the landing page! And a tweet!

@ebelinski

This comment has been minimized.

Copy link

commented Apr 4, 2019

I just tested this on my iPad Pro 9.7" running iOS 12.2 and the latest version of Onion Browser from the App Store. As far as I can tell, my IP gets leaked as well. At first when I visited https://browserleaks.com/ip, it said n/a under "WebRTC Leak Test Public IP address". But then when I refreshed the page, I saw my real IP. See screenshots below.

IMG_0004
IMG_0005

@MarkCallow

This comment has been minimized.

Copy link

commented Apr 7, 2019

I wonder if this was ever really fixed in iOS 12. I'm running iOS 12.1 and I have just discovered that browserleaks.com's "What is my IP Address" page shows my real IP address in its 2-line WebRTC Leak Test section. However the full WebRTC Leak Test page shows "n/a" even after refresh. When I tested in 12.0, I only looked at the WebRTC Leak Test page.

I have no idea what browserleaks.com is doing that would give it different results on these 2 test pages.

@Baccount

This comment has been minimized.

Copy link

commented Apr 8, 2019

@tladesignz have you reported this leak to product-security@apple.com ? They respond quickly and should be able to fix the ip Leak.
https://support.apple.com/en-us/HT201220

@tladesignz

This comment has been minimized.

Copy link
Collaborator

commented Apr 9, 2019

@Baccount Thanks for mentioning that! @mtigas said, he will do this.

I did a little investigation.

The way we do blocking is by injecting either a Content-Security HTTP header or injecting JavaScript.

The "Content Policy" setting is done via the CSP header:

if ([CSPmode isEqualToString:HOST_SETTINGS_CSP_STRICT])
CSPheader = @"connect-src 'none'; default-src 'none'; font-src 'none'; media-src 'none'; object-src 'none'; sandbox allow-forms allow-top-navigation; script-src 'none'; style-src 'unsafe-inline' *; image-src 'unsafe-inline' *; report-uri;";
else if ([CSPmode isEqualToString:HOST_SETTINGS_CSP_BLOCK_CONNECT])
CSPheader = @"connect-src 'none'; media-src 'none'; object-src 'none'; report-uri;";
NSString *curCSP = [self caseInsensitiveHeader:@"content-security-policy" inResponse:response];

The "Allow WebRTC" setting is done via JavaScript injection:

if ("##BLOCK_WEBRTC##") {
navigator.mediaDevices = null;
navigator.getUserMedia = null;
window.RTCPeerConnection = null;
window.webkitRTCPeerConnection = null;
}

It was already mentioned: There's this dedicated WebRTC leak test at Browserleaks:

https://browserleaks.com/webrtc

To mitigate that, the "Allow WebRTC" setting is good enough. You can even have your "Content Policy" set to "Open", which doesn't inject any CSP.

However, the test on

https://browserleaks.com/ip

Isn't mitigated by that at all. The only chance to stop it there, is to completely disable JavaScript. I confirmed this by playing around with the CSP header. Only script-src 'none' or sandbox without allow-scripts stopped it.

So, the only viable mitigation I see at the moment, is to set "Content Policy" to "Strict" by default, which disables JavaScript.

A small UI-side-issue btw. is, that "Allow WebRTC" should be set to "No" when "Content Policy" is set to "Strict", as there's not going to be any WebRTC, if there's no JavaScript running.

Besides that: I tried to poke around in the browserleaks source code from within Safari's console, but that wasn't very effective. Does anybody know, if the source code is public and available?

tladesignz pushed a commit that referenced this issue Apr 9, 2019

Benjamin Erhart
Issue #117: Improve UI for settings: "Content Policy: Strict" can't h…
…ave "Allow WebRTC: Yes". When no JavaScript is run, there's no WebRTC. So mutually exclude these two.

tladesignz pushed a commit that referenced this issue Apr 9, 2019

@MarkCallow

This comment has been minimized.

Copy link

commented Apr 9, 2019

Besides that: I tried to poke around in the browserleaks source code from within Safari's console, but that wasn't very effective. Does anybody know, if the source code is public and available?

I sent an e-mail 2 days ago to the address at the bottom of the browserleaks web page. So far no reply.

@mtigas mtigas pinned this issue Apr 11, 2019

@mtigas

This comment has been minimized.

Copy link
Collaborator

commented Apr 11, 2019

Gah. Tested it more closely this week. Have held off on emailing Apple since I actually don't think this is the same as the iOS 11 Safari/WebKit behavior that revealed true IP even on VPN.

https://d2p12wh0p3fo1n.cloudfront.net/onionbrowser/20190411-130057-1262.mp4

No VPN:

  • Safari: Real IP (i went too fast in this video so it shows "n/a", but webrtc got my real IP in other)
  • Chrome (WKWebView): Real IP (same as above)
  • Endless (UIWebView): Real IP
  • Onion Browser: client ip = Tor IP, webrtc = Real IP

VPN:

  • Safari: VPN IP
  • Chrome (WKWebView): VPN IP
  • Endless (UIWebView): VPN IP
  • Onion Browser: client ip = Tor IP, webrtc = VPN IP

The bad behavior we saw in iOS 11 is that all browsers were leaking Real IP, even if you were connected to a VPN. So the fact that browserleaks correctly shows the VPN IP in all the other browsers, I think, means that this isn't the OS-level issue anymore.

We do override the window.RTCPeerConnection and other related browser APIs to null, injecting this override at the top of every HTML page and JS file loaded:

if ("##BLOCK_WEBRTC##") {
navigator.mediaDevices = null;
navigator.getUserMedia = null;
window.RTCPeerConnection = null;
window.webkitRTCPeerConnection = null;
}

But this is fragile and can be circumvented with some tricks. Below is a fairly simple case. (Console output below leaves out some of the output of intermediate lines to be a bit more readable.)

> window.RTCPeerConnection
< ƒ RTCPeerConnection() { [native code] }

> window.RTCPeerConnection = null;

> window.RTCPeerConnection
< null

> var iframe = document.createElement("iframe");
> document.body.appendChild(iframe);
> window.RTCPeerConnection = iframe.contentWindow.RTCPeerConnection;
< ƒ RTCPeerConnection() { [native code] }

> window.RTCPeerConnection
< ƒ RTCPeerConnection() { [native code] }

(Adapted from http://perrymitchell.net/article/restoring-overridden-window-and-document-methods-with-archetype/ )

The "Disable WebRTC" flag is not bulletproof with JS still enabled. (Same goes for the other things that may be overridden, like navigator.geolocation.getCurrentPosition(...), etc.)

WebRTC seems to be in the same category as embedded media -- videos played inside WebKit don't follow the same TCP stack as our HTTP(S) requests. HTTP(S) requests rely on URLInterceptor being registered to handle all URIs other than file://, data://, and mailto://. But video that are even on HTTP(S) don't appear in the log of things that the app sees through the NSURLProtocol registration.

So, like embedded media, I don't think there's a technical fix here that is 100% bulletproof other than outright blocking JavaScript. (One thing folks have proposed to me: wince we do intercept all content, we could just regex for all JS calls to these things and just strip some of that out of the incoming source before passing it along to the WebKit renderer. But things doing eval() or other workarounds could hide from such a rewriter, dynamically calling things by obfuscated string fn="win"+"dow.RT"+"CPeerConnection" or such. And that's an arms race we don't want to get into.)

So. Ugh. I think the best we can do is an adjustment to the defaults as @tladesignz mentioned, and prioritizing work on changing the settings UI to make clearer what the levels of safety are. (Rather than feature toggle switches that may or may not work, just use a 3-tier slider in line with what Tor Browser does.)

@zoof

This comment has been minimized.

Copy link

commented Jun 5, 2019

I have 12.3 and if I’m understanding it correctly, it appears to be fixed (looks like #117 (comment)). 12.3.1 is available any way to tell if it is safe to upgrade?

@MarkCallow

This comment has been minimized.

Copy link

commented Jun 6, 2019

It is not fixed in 12.3. It was not fixed in 12.1 and probably not in 12.0 either despite what the OB homepage says.

The problem is that if you go to the dedicated WebRTC page, https://browserleaks.com/webrtc, it shows "n/a" for Public IP address giving a false sense of security. However if you go to the overview page, https://browserleaks.com/ip, under WebRTC Leak Test, "Public IP" address shows your real IP address not the Tor IP address.

The OB home page needs to be fixed.

Note: I did not use VPN in my tests.

@zoof

This comment has been minimized.

Copy link

commented Jun 6, 2019

On my device, https://browserleaks.com/ip, the WebRTC Leak Test shows n/a for public IP.

@MarkCallow

This comment has been minimized.

Copy link

commented Jun 6, 2019

@zoof, Did our messages cross or did you not read what I wrote?

@MarkCallow

This comment has been minimized.

Copy link

commented Jun 6, 2019

Sorry, I misread the URL in your comment.

What device do you have? I have an iPad Pro. Try refreshing the page showing https://browserleaks.com/ip.

@MarkCallow

This comment has been minimized.

Copy link

commented Jun 6, 2019

@zoof Did you enable JavaScript? i.e set Content Policy to "No WebXHR/WebSocket/Video connetions?"

@zoof

This comment has been minimized.

Copy link

commented Jun 6, 2019

I have an iPhone SE. Repeated refreshes show Public IP of n/a.

Yes, Content Policy is "No WebXHR/WebSocket/Video connections".

@MarkCallow

This comment has been minimized.

Copy link

commented Jun 6, 2019

Hmm? Very strange. How could the same iOS version, 12.3.1, give different results? Are you sure you are on https://browserleaks.com/ip and not on https://browserleaks.com/webrtc?

@zoof

This comment has been minimized.

Copy link

commented Jun 6, 2019

I have 12.3, not 12.3.1. Definitely https://browserleaks.com/ip.

@ebelinski

This comment has been minimized.

Copy link

commented Jun 6, 2019

@zoof Can you provide a screenshot of the results?

@zoof

This comment has been minimized.

Copy link

commented Jun 6, 2019

Sure.

iOS version:
IMG_0116

https://browserleaks.com/ip:
IMG_0115

@ebelinski

This comment has been minimized.

Copy link

commented Jun 6, 2019

Ah I see, thank you @zoof.

In any case, I have iOS 12.3.1 and my IP is still leaking on https://browserleaks.com/ip. So maybe it was fixed in 12.3, but if it was, this issue is back in 12.3.1. I also tried this on iOS 14 developer beta 1 on an iPhone SE and I still saw my real IP leak.

Overall I'm very concerned for the users of Onion Browser. JavaScript is still enabled by default, and we still do not have a warning on the home page about this issue. This means that effectively all Onion Browser users' identities may be exposed by any website they visit, and they have no way of knowing this, because the average Onion Browser user does not peruse issues on GitHub.

Bad actors can see this issue too and can target Onion Browser users with the information here.

I think we need to take immediate action:

  1. Adding a very visible warning to http://onionbr5zulufnuj.onion/ about this issue.
  2. Pushing an update that disables JavaScript, setting Content policy to Strict for all users.
  3. Adding a warning to the app that alerts user to this issue if they choose to re-enable JavaScript.

Without these changes, all the Onion Browser is doing currently is giving users a false sense of security.

@zoof

This comment has been minimized.

Copy link

commented Jun 6, 2019

Strangely, after playing around with the content policy settings, it now displays my IP address unless I disable everything.

@seanri2112

This comment has been minimized.

Copy link

commented Jun 8, 2019

So I’m one of those that thinks I’m safe when obviously I’m not. I have an iPad Pro 12.9 inch. Strictly WiFi. I have tried everything to find where to disable webrtc and java but I see no clear way of doing that in onion browser. What’s the secret to doing this? Java is disabled in Safari but I’m not using Safari and I see no onion browser in my list of apps in my settings. Any help in my ignorance would be appreciated

@seanri2112

This comment has been minimized.

Copy link

commented Jun 8, 2019

Also when I check my ip over a vpn there is no leak. Is this falsely safe or no better then safari with a vpn?

@ebelinski

This comment has been minimized.

Copy link

commented Jun 8, 2019

Hi @seanri2112, finding this option is a little hard because it's not under the "Global Settings" option that one would normally expect it to be in. Here are the steps to disable JavaScript:

Step 1: Click on the gear icon in the top-right.

IMG_1200

Step 2: Select "Host Settings".

IMG_1201

Step 3: Select "Default Settings".

IMG_1202

Step 4: Select "Content policy".

IMG_1203

Step 5: Select "Strict (no JavaScript, video, etc.)".

IMG_1204

The "Content policy" should now be "Strict".

IMG_1205

@seanri2112

This comment has been minimized.

Copy link

commented Jun 8, 2019

Thanks Ebelinski. Seems so simple now! Haha. Isn’t all this mitigated by just using a vpn with onion?

@tladesignz

This comment has been minimized.

Copy link
Collaborator

commented Jul 12, 2019

@mitgas: Maybe we're able to avert recovering access to WebRTC objects.

Had an interesting discussion.

This is about JavaScript which is injected to resist fingerprinting, but the technique itself maybe works for us, too:

https://github.com/arthuredelstein/browser-privacy/tree/resist-fingerprinting-js
https://github.com/arthuredelstein/browser-privacy/blob/resist-fingerprinting-js/resist-fingerprinting.js
https://github.com/arthuredelstein/browser-privacy/blob/resist-fingerprinting-js/test_protected.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.