Thunderbird allows sender-provided CSS to style the reply and forwarded message
Categories
(Thunderbird :: Security, defect)
Tracking
(Not tracked)
People
(Reporter: me, Unassigned)
References
Details
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:84.0) Gecko/20100101 Firefox/84.0
Steps to reproduce:
- Send/import the following HTML email to Thunderbird:
MIME-Version: 1.0
Content-Type: text/html; charset=us-ascii
<html>
<head>
<style type="text/css">
p { font-size: 0; }
p::before { content: 'Yes, I do.'; font-size: initial; }
p + p { display: none; }
p[_moz_dirty] { display: block; font-size: initial; }
p[_moz_dirty]::before { display: none; }
</style>
</head>
<body>
<div>Hello, do you like my proposal?</div>
</body>
</html>
- Reply to or forward this message with HTML: Click on "Reply" or "Forward" with Shift pressed if you compose messages as plaintext by default. Type something like "No, I don't." into the compose window with the Paragraph style, then click "Send".
Actual results:
The recipient sees "Yes, I do." instead of the "No, I don't.", which the sender wrote. The reason for this is that Thunderbird doesn't restrict the CSS of the quoted message to the quoted message. Instead, the response looks as follows:
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>No, I don't.</p>
<p>I think it's bad.<br>
</p>
<div class="moz-cite-prefix">On 25.01.21 15:53, <a class="moz-txt-link-abbreviated" href="mailto:test@ef1p.com">test@ef1p.com</a> wrote:<br>
</div>
<blockquote type="cite" cite="mid:7qazbuqvovy6tw5wwoe9dg@ef1p.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type="text/css">p { font-size: 0; }p::before { content: 'Yes, I do.'; font-size: initial; }p + p { display: none; }p[_moz_dirty] { display: block; font-size: initial; }p[_moz_dirty]::before { display: none; }</style>
<div>Hello, do you like my proposal?</div>
</blockquote>
</body>
</html>
Expected results:
The recipient should see what the sender wrote. If Alice sends a message to Bob and Bob forwards or replies the message to Carol, then Carol should see what Bob wrote and Alice shouldn't be able to change that. The current situation allows Alice to engineer fake approval/authorization from Bob or to simply insult Carol as Bob, which might cause problems for Bob. The attack isn't perfect: The message preview, which doesn't render CSS, shows Bob response. And of course, Bob and Carol can figure out what is going on by inspecting the raw message.
If you're not convinced that this is a security issue, removing the lines with p[_moz_dirty]
make this at the very least a usability issue as Bob can no longer compose his message. Please note that I tailored this attack for the "Paragraph" style. If the reply is composed in the "Body Text" style, then the above CSS won't work. I didn't invest the time but I'm confident we could make the attack work no matter the chosen style.
Solution: The easiest fix would be to use <style scoped>
in the quoted message – if only this was kept in the standard and got implemented by everyone. Without this, I think the best fix is to prefix all CSS rules in the quoted message with an ID that is generated for the <blockquote>
element. Apple Mail inlines the CSS rules with the style
attribute and Gmail doesn't copy the <style>
element from the <head>
into the reply at all.
Note that another vendor is affected by a similar issue, which I've already reported. Even if you don't think this is a security issue, please don't declassify this issue without my explicit consent. Depending on how things develop, I'm aiming for a coordinated disclosure and I will inform you about the timeline of the other vendor.
PS: I saw that someone else reported presumably the same underlying problem but without the security implications in bug 1668774. In order to keep these implications confidential for now, I've decided to open a new bug report rather than to comment there.
Comment 1•4 years ago
|
||
It's a known issue, and the reason we implemented the mail.html_sanitize.drop_conditional_css pref which makes it harder to pull through - we're aware it's not perfect.
It's indeed a shame <style scoped> didn't make it, so the alternatives for dealing with it are not straight forwards.
I don't think there's a reason to keep this bug marked security sensitive.
Updated•4 years ago
|
Reporter | ||
Comment 2•4 years ago
|
||
Thank you for referencing bug 1530106. I wasn't aware of Jens Müller's research and I found it interesting. I agree that the issue I reported is similar to the one that you referenced. However, I also think that the focus on conditional CSS with @media
and the like distracted from the actual root of the problem: unscoped CSS. As I showed in the example above, one can easily render elements conditionally just by using the descendant combinator. In order to prevent the attack from manifesting itself during message composition, I used [_moz_dirty]
. In order to avoid affecting the original message, I simply didn't use <p>
. Alternatively, I could also have simply reverted the malicious CSS in a blockquote p
rule. If the CSS was scoped and only affected elements in the original message, then @media
rules wouldn't have been problematic because it's clearly visible that this is in the attacker's and not the victim's message.
Having said that, scoping alone isn't sufficient to address such "message injection attacks". You should also disallow/filter the position
property. Web clients handle this quite well. (I didn't bother to test relative positioning as well.) In other words, even with inline CSS, which doesn't support CSS selectors at all, an attacker can still overlay the victim's message with their own (by using something like position: absolute; top: 0; left: 0; background-color: white;
). [Update: I didn't get the background-color to work. Instead of overlaying the victim's message, the attacker might only be able to extend the victim's message.] Since this CSS is also applied when composing a message, the victim might realize that something is wrong. On the other hand, if the attacker uses position: relative
, the malicious overlay might only become visible on narrow screens. For reference, Gmail doesn't support the position
property at all. And if you filter the position
property, you should also filter negative margins.
Regarding confidentiality: I agree that the attack vector itself has to be considered to be publicly known, so I leave it to you whether you want to disclose this report. I haven't received anything besides a generic reply from the other vendor yet but I think that publishing this report doesn't affect my responsible disclosure with them.
Comment 3•4 years ago
|
||
While we'd certainly like to improve this, it's technically difficult. This is more or less bug 31052 (which is very old).
Reporter | ||
Comment 4•4 years ago
|
||
By the way, what was mentioned in comment 13 of the other issue is still a problem but every mail client I checked has it. In my opinion, mail clients should either not generate a plaintext part when quoting an HTML email or force all text in HTML emails to render (i.e. filter all properties that Jens Müller mentioned in table 1 of his paper).
For example, if your boss uses an HTML-capable client and your accountant uses a plaintext-only client, then the reply to all with Yes, I can confirm this.
by your boss will be interpreted differently by the accountant:
<html>
<body>
Hi boss, can you confirm to our accountant in CC that my monthly salary is
increased by USD 100<span style="font-size: 0;">0</span> starting next month?
</body>
</html>
Unfortunately, not quoting the previous message and simply relying on the In-Reply-To
header doesn't solve the problem. In combination with multipart/alternative
, the In-Reply-To
header seems to be fundamentally broken and I don't see anything that mail clients can do about this.
Reporter | ||
Comment 5•4 years ago
|
||
Here is my write-up of this issue: https://explained-from-first-principles.com/email/#quoting-html-messages
Updated•2 years ago
|
Description
•