Bringing E2E privacy to the Web: 4th security audit 😅

May 22, 2023 by holga

Delta Chat’s “web apps shared in a chat” come with a unique privacy promise but in January it was shown to be compromised. We got into a surprising struggle with Web browser sandboxing issues that took us several months to come out ahead of.

This post provides the background story of this struggle leading to the security-hardened Delta Chat 1.36 release series in April 2023.

The unique privacy promise of web apps without tracking or platforms

Unlike Telegram with its Bots or WeChat with its MiniApps, Delta Chat allows anyone to create and share web apps in a chat while maintaining the industries strongest privacy promise: web app developers or distributors can not track or control you because web apps run in a browser sandbox without internet access and can only exchange messages with other app instances by relaying through our security-audited Rust core library. Delta Chat completely bars browsers from doing any network requests themselves.

Enforcing this privacy promise depends on our ability to safely run web code in a network-isolated webview to prevent it from causing unwanted network traffic. We generally use standard Browser APIs and Content-Security-Policy directives to prevent web code from unwanted network access, such that:

Mid 2022 we developed a webxdc test app to verify these guarantees and tested it on many devices until we were sure we could run isolated webviews for users.

Or so we thought.

WebRTC breaks the sandbox and it’s hard to fix it

In January 2023, a new contributor, WofWca, discovered that RTCPeerConnection objects are not restricted by the known network-isolation options for webviews or Content-Security-Policies that try to isolate parts of web pages. RTCPeerConnection objects are the core programmatic offering of WebRTC protocols which allow P2P communications for video or data transfers.

Our privacy promise was broken and an example exploit showcased it.

We convened a “DISABLE-WEBRTC” working group from our team and befriended experts to iteratively implement and develop mitigations to enforce network-isolation of webviews, both for Chromium and Webkit/iOS. Not even all Delta Chat contributors knew of the massive work taking place behind the scenes and only surfacing in various PRs in public repositories.

Fill500: Disabling WebRTC on Chromium

After many days of reading Chromium source code, trying and testing, we came up with this little snippet that needs to run before we start web apps:

// FILL500: Disable WebRTC on Chromium
for (let i = 0; i < 500; i++) {
    new RTCPeerConnection()

This is not a copy-paste error but the actual fix. Now, let us explain why it works:

Special care still needed to be taken that neither navigation or iframe-constructions can create a new pool of RTCPeerConnections.

We’ll skip on the details of that but it involved trying various Chromium variants and finding more surprises that needed modified mitigations or controls to prevent apps from getting a new RTCPeerConnection pool. Note that FILL500 can cause delays of sometimes 3-5 seconds for starting web apps on old phones. It’s not pretty but we consider our privacy promise more fundamental. Web and Chromium experts from various projects and groups could not improve on FILL500.

If anyone has a better fix for preventing RTCPeerConnections, please come forward. This blog post like all older ones can be commented on in the Fediverse, see the bottom of the post.

Disabling WebRTC worked in February on all platforms but …

FILL500 is used on Android and Electron-based Desktop. For webkit/iOS (used by Safari), DISABLE-WEBRTC mitigations work differently: the RTCPeerConnection object is removed from JavaScript namespaces such that web apps can not get a reference to RTCPeerConnection objects at all. The mitigation consisted in a just a few lines of code when creating the web view.

Beginning February 2023 Delta Chat apps on all platforms were released containing DISABLE-WEBRTC mitigations.

Meanwhile OpenTechFund had thankfully agreed to contract Cure53 to perform a thorough security audit of our mitigations and of webxdc security and privacy promises in general. No compromise against our Disable-WebRTC mitigations was found but it unfortunately wasn’t the end of an already exhausting story …

DNS-prefetching marks another exploit

Security auditors from Cure53 found another issue which sent us back to the drawing board and lots of head scratching: Chromium performs “DNS-prefetching” which aims to speed up browsing experiences for users by performing DNS network queries before a user clicks on any link or the page requests a resource. Auditors provided two exploits for Desktop and Android respectively which could exfiltrate data from web apps via Chromium’s DNS-prefetch feature. Unfortunately, the official suggestion for disabling DNS-prefetch on Chromium does not work. We found in Chromiums source code tests that dns-prefetch “off” settings can be manually overriden.

To cut another longer story short here, we’ll found working mitigations (see next section) so that webxdc apps can not leak data anymore via DNS-prefetch.

Addressing the 4th security audit for running web apps safely

The Cure53 security audit about webxdc apps identified five “high” and two “info” severity issues with our February releases. Here we provide a summary of the issues and links to our fixes:

All high-severity issues are fixed with the 1.36 release series already published to app stores and our web page in April.

Take aways on better browser sandboxing

We were a bit naive thinking that Web Browsers and especially Chromium sandboxes allow to control network access on web views. Then again, with web browsers and their sandboxing models used for a lot of commercial and payment activities, with tons of third-party code running on user’s Browsers, we did not expect it would be so hard to control the network behaviour of web code.

Browsers: please implement the W3C “WEBRTC: block” directive

Platforms serving web pages or apps need to trust their complete supply chain of JavaScript dependencies if they don’t want users of their offerings to leak app data through WebRTC. Most importantly, Content-Security-Policies do not prevent leakage currently. The issue is actually long known, see the WebRTC can be used for exfiltration issue from 2016.

In 2022 the W3C finally adopted a direct method to disable WebRTC via a WebRTC: Block CSP setting but it’s not implemented yet by browsers. The WebRTC CSP would allow webxdc and web2 applications and platforms a much saner way to control Browsers and for Chromium in particular getting rid of the FILL500 hack. Many thanks to ZenHack who persevered in landing this new CSP directive and even went through the bureaucratic effort of becoming a registered W3C spec contributor to land it.

Reminder: VPN users might leak IP address through WebRTC

It is also a well-known issue when using VPNs that WebRTC can cause local IP address leaks. A search on DuckDuckGo reveals many old and recent blog posts and VPN provider pages advising on mitigating the issue. However, two sets of expert groups have not found a way to disable WebRTC on Chromium other than the hacky FILL500 algorithm above and we are not aware of any other browser-level method to reliably disable WebRTC on Chromium. Some VPN setups may succeed however in preventing WebRTC connections on the network level but you will need to inquire yourself with your VPN providers to find out. We think Browsers should up their game and allow users to consent to using WebRTC similar to Camera/Microphone permissions.

If you depend on using a VPN then it’s for now maybe safer to use Firefox based engines (Tor is also firefox-based) and ensure WebRTC is disabled (see below) because otherwise you might leak your actual IP address to malicious web sites that try to identify VPN users.

Maybe using Firefox engines would help us?

Delta Chat apps do not use Firefox webviews which can be directly configured to disable WebRTC, by setting media.peerconnection.enabled = false in about:config. Firefox can do DNS-prefetching but it thankfully again appears like there are simple configurations to disable it. However, the Delta Chat desktop app uses Electron which in turn uses Chromium and on Android devices the system webview is typically a Chromium webview. We investigated whether we could use GeckoView and early tests confirm it would solve the WebRTC issue.
But shipping GeckoView within Delta Chat is a) still quite a bit of work b) would drastically increase the APK size. We are nevertheless considering it especially if Chromium does not implement the “WebRTC: Block” directive sometime.

Combining the Servo Rust engine with Delta Chat’s Rust core?

Like many other developers who are critical of Google’s dominance with Browsers we were sad to see Mozilla let go of their Servo team. But recently Servo is picking up steam again and Igalia wants to help revive Servo. Maybe it becomes feasible to integrate Servo at some point?

For sure, webxdc apps are a young feature which we want to further evolve in 2023, exploring and creating realities where open web technology integrates with E2E messaging instead of today’s centralized platforms. Please see our donate page if you can support us or want to get involved. Thanks!

Show Comments

You can reply on any Fediverse (Mastodon, Pleroma, etc.) website or app by pasting this URL into the search field of your client: