Critical vulnerabilities exist in several JSON Web Token (JWT) libraries – namely the JavaScript and PHP versions – that could let an attacker bypass the verification step.
Tim McLean, a Canadian security researcher who specializes in cryptography and dug up the issues, points out that attackers could exploit one of those vulnerabilities, which abuses an asymmetric signing algorithm, in some JWT libraries.
Introduced a few years back, JWT is a standard that produces tokens between two parties. For example, a server can produce an admin token, transferred in JSON, and signed by the server’s key. Clients can go on to use that token to verify the user is logged in as an admin.
The issue revolves around a public key confusion between systems signed with the hash function HMAC and those signed with RSA.
“If a server is expecting a token signed with RSA, but actually receives a token signed with HMAC, it will think the public key is actually an HMAC key,” McLean explained in a blog post Tuesday. “How is this a disaster? HMAC secret keys are supposed to be kept private, while private keys are well, public.”
In this scenario if an attacker got access to a public key, through an API in some JWT libraries, they could use it as a token and the server would accept it.
When reached by email on Wednesday McLean says he first found the vulnerabilities back in January when he was looking to use JWT in a project. Upon combing through the libraries – something he admits has taken some time, as he’s been doing the work in his free time – McLean discovered the crypto wasn’t correctly implemented.
To address the issue, he’s advising anyone who runs a JWT implementation to verify that tokens with different signatures are set up to be rejected either via a whitelisting or blacklisting mechanism.
“The server should already know what algorithm it uses to sign tokens, and it’s not safe to allow attackers to provide this value.”
A separate issue, since fixed in many JWT libraries, previously let attackers choose the way tokens are verified, a condition that had “disastrous implications for some implementations,” according to McLean.
McLean initially blogged about the issue in February and elaborated further on the issue this week. Auth0, one of the most popular ways to implement authorization standards, found his research so important, it republished the work on its own blog yesterday.
This issue is rooted in the way that some libraries handled an algorithm known as “none.” Tokens signed with “none” could have be acknowledged as valid tokens with valid signatures, according to McLean. Attackers could modify tokens and sign them with “none” instead of HMAC-SHA256, or HS256. The tokens would then appear “signed.” Attackers then could have gone on to attach their own payload to gain arbitrary account access on some systems.
According to McLean most libraries have fixed the “none” issue by ensuring that token verification fails any tokens that use the “none” algorithm, but it was through that issue that he discovered the asymmetric keys problem.
“Initially, I was satisfied with the ‘none’ problem, but a lot of implementers were just disabling the “none” alg instead of fixing the underlying problem (attacker-controlled algorithm), so I took another look at how I could exploit it,” McLean said.
McLean has been trying to address the asymmetric keys issue with the help of Auth0, who’s helped him got in touch with several authors of the vulnerable libraries to make sure that any tokens with a different signature type are inherently rejected. Since JWTs can work across several languages, .NET, Node.js, Python, PHP, Java, Ruby, to name a few, there were a handful of libraries to contact about the vulnerability.
If you wrote a JSON Web Tokens library and haven’t heard from me, could you contact me please? #jwt #jws #jose #websecurity #vulnerabilities
— Tim McLean (@McLean0) March 18, 2015
Auth0 fixed the issue in its Node.js library last Thursday and is encouraging users to upgrade to 4.2.2, the latest version.
IMPORTANT: Critical vulnerabilities in JWT libraries. Auth0 customers not affected. More: https://t.co/GFZPTuny8n pic.twitter.com/BHWNDNTiBn
— Auth0 (@auth0) March 31, 2015
Jose Padilla, who maintains the Python build of the library, fixed the signature verification vulnerability in version 1.0.0 last month by adding support for an alg
whitelist. The most recent version, 1.0.1, also includes the fix.
Just released PyJWT v1.0.0 #python https://t.co/iixDhBNK0w
— José Padilla (@jpadilla_) March 18, 2015
According to jwt.io, a service run by Auth0, the PHP or JavaScript versions of the libraries remain vulnerable. Auth0 is instructing those who run those versions of JWT in particular to seek out another non-vulnerable library until the issues are fixed or verified.
McLean, who sent out a mass email about the issue to over 20 library maintainers on March 9, hasn’t heard back from them all but pointed out that while Auth0 doesn’t mention it the Ruby version of the library is still vulnerable as well.
“There are so many JWT libraries that I don’t actually have enough time to review them all,” McLean said.
McLean is hoping his blog post helps future JWT implementers understand some of the precautions that should be taken before deploying it in the wild but believes a change to the spec, deprecating the header’s alg field, would ultimately benefit the community. McLean submitted his post to the Javascript Object Signing and Encryption (jose) working group and hopes they’ll take notice.