Full Report
Skiff is an email provider that really doesn't want XSS on their website. First, they sanitize their emails using DOMPurify. After that, they do various transformations on the data, which is the crux of the issue. They stick the email rendering into an iFrame and have a good CSP as well. Let's bypass all of them! Mutation XSS (mXSS) is a type of XSS that results from taking information, but the browser fixing the markup changes the expected meaning of it. A good example of this can be seen here. In Skiff, the content is ran through DOMPurify then processed some more. During this processing, the previously quoted emails are put into a thread, which inserts an empty div before the first element with the parameters data-injected-id=last-email-quote. So, what's the big deal with this small change? In HTML, a div is invalid within an svg tag. So, if the browser sees this it will move the entire div element outside of the svg. Many of the elements within the svg that are safe there are unsafe in the normal context. Using some weirdness with style tags closing within double quotes in the HTML context but not the SVG context allows for the smuggling of an image tag with a onerror event! This gives us XSS within the iFrame. The iFrame for Skiff has three directives on it: allow-same-origin, allow-popups and allow-popups-to-escape-sandbox. The goal is to get code that we can execute on the page. To do this, they first noticed that images are rendered as inline blobs. Since blobs inherit the origin they are on, we can create an attachment with the necessary information in a blob. The blobs have a random UUID though. So, using a technique in a previous post, they use CSS to leak the UUID to themselves. Once they know the UUID of the attachment, they put the attachment into a link for the victim to click in a follow-up email. By having the link contain target="_blank", this will be opened in another tab with the content being controlled by us. The final thing was bypassing the CSP. The CSP contains script-src 'unsafe-eval' http://hcaptcha.com. This is known to have an XSS gadget. So, an attacker can simply use one of these existing functions to get the XSS working. Overall, a pretty crazy XSS bug with a full CSP bypass and sandbox escape. To me, CSPs and iFrames seem unescapable. So, finding posts that circumvent these protections is pretty amazing.
Analysis Summary
# Vulnerability: Mutation XSS Leading to Sandbox Escape and CSP Bypass in Skiff Web Client
## CVE Details
- CVE ID: Not specified in the text.
- CVSS Score: Not specified in the text. (Severity implied as Critical due to impact: Steal decrypted emails, impersonation).
- CWE: CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
## Affected Systems
- Products: Skiff Email Web Client (End-to-end encrypted email provider).
- Versions: Prior to the fix deployed on June 30, 2022.
- Configurations: Viewing a specially crafted malicious email, followed by clicking a link in a subsequent email.
## Vulnerability Description
The vulnerability is a complex **Mutation XSS (mXSS)** issue within the Skiff web client, which processes and renders user-controlled email content.
1. **Initial State:** Skiff uses DOMPurify to sanitize incoming email HTML before rendering.
2. **The Flaw:** After DOMPurify sanitization, Skiff processes the data further by injecting an empty `<div>` element with the attribute `data-injected-id=last-email-quote` before elements related to quoted emails within the thread view.
3. **mXSS Trigger:** When rendering this modified content within an `<iframe>` (which Skiff uses for email display), the presence of a `<div>` element inside an `SVG` tag is technically invalid HTML. The browser attempts to correct this by moving the invalid `<div>` element outside the surrounding `SVG`.
4. **Exploitation Primitive:** This structural change causes elements that were safe within the `SVG` context to be rendered in the main HTML context, where they become unsafe. Specifically, this allowed the smuggling of an `<image>` tag containing an `onerror` event handler by leveraging quirks related to how `<style>` tags close quotes, leading to XSS execution inside the rendering iframe.
5. **Sandbox and CSP Bypass:** The resulting XSS in the iframe had `allow-same-origin`, `allow-popups`, and `allow-popups-to-escape-sandbox` enabled. The attacker leveraged inline image blobs (which inherit the origin) to leak a unique UUID via CSS styling. Once the UUID was known, the attacker constructed a subsequent email link with `target="_blank"`. When clicked, this opened a new tab controlled by the attacker. A final bypass of the `script-src 'unsafe-eval' http://hcaptcha.com` Content Security Policy (CSP) was achieved by utilizing a known XSS gadget within the whitelisted `hcaptcha.com` domain.
## Exploitation
- Status: Proof-of-Concept (PoC) available, demonstrated by the researchers. No signs of in-the-wild exploitation reported.
- Complexity: High (Required multiple carefully crafted emails, timing, knowledge of mXSS, DOM mutation, blob origin inheritance, CSS leakage of UUID, sandbox escape, and CSP gadget usage).
- Attack Vector: Network (Victim receives and views malicious emails).
## Impact
- Confidentiality: High (Attacker could steal decrypted emails and private keys).
- Integrity: High (Attacker could fully impersonate victims).
- Availability: Low (The primary goal was data theft and impersonation, not service denial).
## Remediation
### Patches
- The vulnerability was fixed by the Skiff team on **June 30, 2022**. The specific patch details are not provided, but the timeline suggests the fix prevented the post-sanitization modification of the HTML DOM structure that caused the mutation.
### Workarounds
- Never modify or re-parse HTML after sanitization.
- If sanitizing, configure DOMPurify to return the sanitized DOM tree directly rather than a string, and insert the tree without further manipulation.
- Use client-side sanitization with state-of-the-art tools.
## Detection
- **Indicators of Compromise (IOCs):** Excessive network connections originating from the client environment associated with CSS property checks against unique blob URLs/UUIDs derived from attachments. Unusual activity logging related to embedded link clicks opening new tabs (`target="_blank"`).
- **Detection Methods and Tools:** Monitoring for DOM mutations that move elements between expected contexts (e.g., migrating elements out of an SVG context). Analyzing post-sanitization data processing steps for structural alterations to sanitized input.
## References
- Vendor Disclosure/Fix Timeline: June 2022.
- Sonar Research Blog Post: hxxps://www.sonarsource.com/blog/code-vulnerabilities-put-skiff-emails-at-risk/
- Black Hat Asia 2023 Talk (Video available): hxxps://www.youtube.com/watch?v=pnbZMvCPqSc