Full Report
Proton Mail is a privacy-centric email service. Being able to extract secrets from this service, where it's supposed to be secret, would be devastating. Under the hood, it uses the state-of-the-art HTML sanitizer DOMPurify in order to avoid XSS on incoming emails. After doing the sanitization via DOMPurify, the author noticed that some DOM manipulation was being done. In particular, the code would find and replace them with . It may be possible to use this to break the parsing of the HTML! HTML has its own parsing rules. However, SVG and MathML have their own rules. For the tag, the parsing is different when seeing a closing tag. In HTML, the text in the next closing style tag will end. In SVG, it can contain child elements. Seeing the code in different contexts can cause major issues. When the element is changed from an svg to proton-svg, major changes occur to the parsing. Using the payload and changing the context will cause the style to get parsed differently. Originally, the text was kept in for svg, since it was valid. But, the transformation leads to issues with the context, potentially leading to XSS. Adding a will now lead to XSS! But, we still have two more lines of defense. First, there's an iframe. Second, there's a CSP. For the iFrame on Safari, it adds the directive allow-scripts directive, which allows attackers to execute JS to access the top frame. The allow-popups-to-escape-sandbox element allows JS to access the other page that popped the iFrame. For other browsers, the attacker needs a victim to click on a link that opens in a new tab, which will then access the rest of the content on the website. The final thing is bypassing the CSP. The CSP restricts which origins information can be loaded from. In the CSP, the blob URi was allowed for scripts. They are temporary URLs that can be dynamically created at a link then used. If we can convince the browser to load our blob, we'd be able to execute arbitrary JS. The blob URLs are placed at long UUIDs. Since these are random, we need a way to know where these are. In order to do this, the author used the ability to render remote images and inline styles to leak the original URL. Then, later, use this blob URL in a different payload. Overall, an awesome post on contexts for HTML parsers, escaping iFrame sandboxes and CSP bypasses. I really enjoyed the post and learned a ton along the way.
Analysis Summary
# Vulnerability: Mutation XSS (mXSS) via Post-Sanitization DOM Manipulation in Proton Mail
## CVE Details
- **CVE ID:** Not explicitly assigned in the report (Internal bug bounty discovery)
- **CVSS Score:** ~8.1 (High) - *Estimate based on impact (Total compromise of E2EE emails)*
- **CWE:** CWE-79 (Cross-site Scripting), CWE-116 (Improper Encoding or Escaping of Output)
## Affected Systems
- **Products:** Proton Mail Web Client
- **Versions:** Versions prior to June 2022
- **Configurations:** Web browsers (specifically Safari for sandbox escapes); impacts users reliant on End-to-End Encryption (E2EE).
## Vulnerability Description
The flaw originates from the **modification of HTML content after it has been sanitized**. Proton Mail used DOMPurify to clean incoming emails; however, post-sanitization code performed a find-and-replace operation on tags (e.g., changing `<svg>` to `<proton-svg>`).
This modification triggers a "Mutation XSS" (mXSS). HTML, SVG, and MathML have differing parsing rules. Specifically, the `<style>` tag is parsed as raw text in an HTML context, but can contain child elements in an SVG/MathML context. By forcing a context switch through tag renaming, attackers can hide malicious payloads within a `<style>` block that DOMPurify deems safe, which then "breaks out" and executes as JavaScript once the browser re-evaluates the mutated DOM.
## Exploitation
- **Status:** PoC available (demonstrated by Sonar Research); No known in-the-wild exploitation.
- **Complexity:** High (Requires bypassing Sanitization, iFrame Sandboxes, and CSP).
- **Attack Vector:** Network (Email-based).
The exploit requires two emails:
1. **Email 1:** Leverages remote image loading and CSS to leak a unique **Blob URL** (UUID) created by the app.
2. **Email 2:** Uses the leaked Blob URL to bypass the Content Security Policy (CSP), which allowed `blob:` sources for script execution.
## Impact
- **Confidentiality:** High (Attacker can read decrypted emails and potentially private keys).
- **Integrity:** High (Attacker can impersonate the victim and send emails).
- **Availability:** Low (Primary goal is data theft/impersonation).
## Remediation
### Patches
- Proton Mail pushed a fix to their public repository on **2022-06-15** and deployed it to production on **2022-07-06**. Users are protected by using the latest web interface.
### Workarounds
- Disable the rendering of SVG and MathML content if the mail client allows such configuration.
- Avoid clicking links in suspicious emails that open in new tabs (to prevent `opener` based sandbox escapes).
## Detection
- **Indicators of Compromise:** Unusual outbound network requests to attacker-controlled domains (used for leaking Blob URLs via CSS/images); presence of `<proton-svg>` or `<proton-mathml>` tags containing unexpected nested elements in mail source.
- **Detection Methods:** Security researchers should audit code for any logic that manipulates HTML strings *after* a sanitizer like DOMPurify has run.
## References
- Sonar Blog: hxxps[://]www[.]sonarsource[.]com/blog/code-vulnerabilities-put-proton-mails-at-risk/
- Black Hat Asia 2023 Presentation: "Stealing with Style: Using CSS to Exploit ProtonMail & Friends"
- DOMPurify Security Documentation: hxxps[://]github[.]com/cure53/DOMPurify