Critical flaw alert! Stop using JSON encryption

Developers shouldn't use JSON Web Tokens or JSON Web Encryption in their applications at all, lest their private keys get stolen

Thinkstock

A vulnerability in a JSON-based web encryption protocol could allow attackers to retrieve private keys. Cryptography experts have advised against developers using JSON Web Encryption (JWE) in their applications in the past, and this vulnerability illustrates those very dangers.

Software libraries implementing the JWE, or RFC 7516, specification suffer from a classic Invalid Curve Attack, wrote Antonio Sanso, a senior software engineer at Adobe Research Switzerland and part of the Adobe Experience Manager security team. The JSON Web Token (JWT) is a JSON-based open standard defined in the OAuth specification family used for creating access tokens, and JWE is a set of signing and encryption methods for JWT. Developers using JWE with Key Agreement with Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES) are affected.

A quick primer in elliptic curve cryptography is in order to understand the Invalid Curve Attack. ECC is a way to calculate public-private key pairs based on the algebraic structure of elliptic curves over a finite data set. The order of the elliptic curve is big enough that it becomes difficult for an attacker to try to guess the private key. ECDH-E is a key exchange mechanism based on elliptic curves, and it's used by websites to provide perfect forward secrecy in SSL.

The Invalid Curve Attack lets attackers take advantage of a mathematical mistake in the curve's formula to find a smaller curve. Because the order of the smaller elliptic curve is more manageable, attackers can build malicious JWEs to extract the value of the secret key and perform the operation multiple times to collect more information about the key.

The Invalid Curve Attack was first published 17 years ago, and it was described in a 2014 talk on elliptic curve cryptography at Chaos Communication Congress in Hamburg by Tanja Lange, a professor of cryptology at the Netherlands' Eindhoven University of Technology and Daniel J Bernstein, a mathematician and research professor at the University of Illinois at Chicago. The problems have been in the open for a long time, but Sanso found that several well-known libraries using RFC 7516 were vulnerable to the attack.

Developers who rely on libraries go-jose, node-jose, jose2go, Nimbus JOSE+JWT, or jose4 with ECDH-ES should update their existing applications to work with the latest version and make sure they are using the latest version for all new code. The updated version numbers are the following: node-jose v0.9.3, jose2go v1.3, jose4 v0.5.5 and later, Nimbus JOSE+JWT v4.34.2, and go-jose.

"At the end of the day the issue here is that the specification and consequently all the libraries I checked missed validating that the received public key (contained in the JWE Protected Header) is on the curve," Sanso wrote.

The exposed vulnerability was due to a gap in the RFC 7516 specification, and as most implementers would follow the specification directly, they unintentionally introduced the vulnerability into their libraries, said Matias Woloski, CTO and Co-Founder of Auth0, a universal identity platform.

"It's a rare case where the flaw was in the specifications design and not the implementation," Woloski said.

The default Java SUN JCA provider, which comes with Java prior to version 1.8.0_51, is also affected, but later Java versions and the BouncyCastle JCA provider are not. It appears that the latest version of Node.js is immune to this attack, but Sanso warned it was still possible to be vulnerable when using browsers without support for web cryptography.

As part of his research, Sanso set up an attacker application on Heroku. When users clicks on the "recovery key" button on the app, they'll be able to see how the attacker recovers the secret key from the server. The code for demonstration and proof-of-concept are available on GitHub.

Luckily, the impact may be limited, as JWE with ECDH-ES is not widely used. 

Developers who decide to go with JWT are trying to avoid having to use server-side storage for sessions, but they wind up turning to wacky workarounds instead of careful engineering, said Sven Slootweg Cryto Coding Collective. With JWE, developers are forced to make decisions on which key encryption and message encryption options to adopt -- a decision that shouldn't be left up to noncryptographers.

"Don't use JWT for sessions," said Slootweg. "The JWE standard is a minefield that noncryptographers shouldn't be forced to navigate."

Instead, developers should stick with sessions, using cookies delivered securely over HTTPS. The library libsodium also offers developers a tried and tested method of using signatures via crypto_sign() and crypto_sign_open(), or encryption via the crypto_secretbox() and crypto_box() APIs.

Library developers and engineers working with security-focused libraries need to make sure they stay up to date with the latest developments, so they can be ready to patch the issues. "The specification designers (often from industry) should be more proactive in engaging the research community to evaluate the security of specifications in a proactive (pre-standardization) instead of reactive way," Woloski said.

More cryptographers need to review software libraries that developers use to make sure the algorithms are implemented correctly. All too often, the people working on the specifications have little to no contact with researchers.

The issue was reported to the JavaScript Object Signing and Encryption working group's mailing list. This advisory also highlights why specifications should never be considered a static document: They must be revisited and updated periodically to reflect any detail that was initially overlooked or changed based on available new information.

"We all seem to agree that an errata [on the specification] where the problem is listed is at least welcomed," Sanso wrote.