Exploiting flawed JWT signature verification

Exploiting flawed JWT signature verification

Accepting arbitrary signatures

JWT libraries typically provide one method for verifying tokens and another that just decodes them. For example, the Node.js library jsonwebtoken has verify() and decode().

Occasionally, developers confuse these two methods and only pass incoming tokens to the decode() method. This effectively means that the application doesn't verify the signature at all.

Lab

This lab uses a JWT-based mechanism for handling sessions. Due to implementation flaws, the server doesn't verify the signature of any JWTs that it receives.

To solve the lab, modify your session token to gain access to the admin panel at /admin, then delete the user carlos.

You can log in to your own account using the following credentials: wiener:peter

Steps

  • Install JWT Editor burp suite extension

  • Visit the target website

  • Login as wiener and peter as username and passwords

  • Visit the /admin route

  • Send the /admin request to the repeater

  • In the repeater click the JSON Web Token Tab

  • Change the username from wiener to administrator and send the request

  • Now copy the new JWT token

  • Send the the request and in the proxy tab remove the old jwt session token and paste the new jwt token to delete the user carlos.

  • $$$


Accepting tokens with no signature

Among other things, the JWT header contains an alg parameter. This tells the server which algorithm was used to sign the token and, therefore, which algorithm it needs to use when verifying the signature.

{
    "alg": "HS256",
    "typ": "JWT"
}

This is inherently flawed because the server has no option but to implicitly trust user-controllable input from the token which, at this point, hasn't been verified at all. In other words, an attacker can directly influence how the server checks whether the token is trustworthy.

JWTs can be signed using a range of different algorithms, but can also be left unsigned. In this case, the alg parameter is set to none, which indicates a so-called "unsecured JWT". Due to the obvious dangers of this, servers usually reject tokens with no signature. However, as this kind of filtering relies on string parsing, you can sometimes bypass these filters using classic obfuscation techniques, such as mixed capitalization and unexpected encodings.

Note

Even if the token is unsigned, the payload part must still be terminated with a trailing dot.

Lab

This lab uses a JWT-based mechanism for handling sessions. The server is insecurely configured to accept unsigned JWTs.

To solve the lab, modify your session token to gain access to the admin panel at /admin, then delete the user carlos.

You can log in to your own account using the following credentials: wiener:peter

Steps

  • Install JWT Editor extension in burp suite

  • Visit the website and login as wiener:peter

  • Visit the /admin route

  • Send the request to repeater

  • In the repeater tab visit the JSON Web Token Tab

  • Change the "alg" value to "none"

  • and copy the new jwt token (teminate the signature section but keep the dot)

  • In the proxy tab replace the token with the new jwt token

  • This will delete the user carlos

  • $$$

Last updated