🥰JWT attacks

Today i will Explain what is JWT & Attacks & Portswigger labs in a basic way , i hope this blog will be useful for you :

What is JWT ?

  • JWTs are most commonly used in authentication, session management, and access control mechanisms

  • JSON web tokens (JWTs) are a standardized format for sending cryptographically signed JSON data between systems

  • Unlike with classic session tokens, all of the data that a server needs is stored client-side within the JWT itself

  • JWT attacks involve a user sending modified JWTs to the server , this goal is to bypass authentication and access controls by impersonating another user who has already been authenticated.

JWT format :

  • A JWT consists of 3 parts: a header, a payload, and a signature. These are each separated by a dot, as shown in the following example:

    1. header : header contains metadata about the token itself (encryption algorithm)

    2. payload : information about the permission of current user (privilege)

    3. signature : the result of hashing header + payload , In some cases, they also encrypt the resulting hash & this process involves a secret signing key

      • As the signature is directly derived from the rest of the token, changing a single byte of the header or payload results in a mismatched signature.

      • Without knowing the server's secret signing key, it shouldn't be possible to generate the correct signature for a given header or payload

      • The header and payload parts of a JWT are just base64url-encoded JSON objects.

    JWT vs JWS vs JWE :

    • JWT : very limited , only defines a format for representing information as a JSON object that can be transferred between two parties

      1. JWTs aren't really used as a standalone entity كيان مستقل

      2. The JWT spec is extended by both the JSON Web Signature (JWS) and JSON Web Encryption (JWE)

      3. JWT is usually either a JWS or JWE token. When people use the term "JWT", they almost always mean a JWS (Siganture) token.

      4. JWEs but the difference is the token are encrypted not encoded.

JWT header parameter injections :

  • JWT headers (also known as JOSE headers) often contain several other parameters

    1. JWK (JSON Web Key) ⇒ Provides an embedded JSON object representing the key.

    2. JKU (JSON Web Key Set URL) - Provides a URL from which servers can fetch a set of keys containing the correct key.

    3. kid (Key ID) - Provides an ID that servers can use to identify the correct key in cases where there are multiple keys to choose from.

How do JWT attacks arise?

  1. arise due to flawed JWT handling within the application itself.

  2. the signature of the JWT is not verified properly.

  3. If this key is leaked in some way or can be guessed or brute-forced, an attacker can generate a valid signature

Impact :

  • If an attacker is able to create their own valid tokens with arbitrary values, they may be able to escalate their own privileges or impersonate other users, taking full control of their account

what is flawed JWT signature verification ?

  • it mean that the servers don't usually store any information about the JWTs that they issue. Instead, each token is an entirely self-contained entity.

  • it lead to the server doesn't know the original contents of the token, or what the original signature was.

  • For example, consider a JWT containing the following claims:

    {
        "username": "carlos",
        "isAdmin": false
    }

    If the server identifies the session based on this username, modifying its value might enable an attacker to impersonate other logged-in users. Similarly, if the isAdmin value is used for access control, this could provide a simple vector for privilege escalation.

Scenario :

  1. Unverified Signature :

    • JWT libraries typically provide 2 method verify() and decode().

    • here developer just use decode() method without verify()

  2. Accepting tokens with no signature :

    • JWT header contains an alg parameter. This tells the server which algorithm was used to sign the token

    • some times alg parameter is set to none and must still be terminated with a dot.

  3. try to Brute-forcing secret keys like HS256 algorithm

    • try crack the token

    • if crack done then create a new signature

  4. Injecting self-signed JWTs via the jwk parameter

    • A JWK (JSON Web Key) is a standardized format for representing the keys as a JSON object.

    • You can exploit this behavior by signing a modified JWT using your own RSA private key, then embedding the matching public key in the jwk header.

      JWT header 
      {
          "kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG",
          "typ": "JWT",
          "alg": "RS256",
          "jwk": {
              "kty": "RSA",
              "e": "AQAB",
              "kid": "ed2Nf8sb-sD6ng0-scs5390g-fFD8sfxG",
              "n": "yy1wpYmffgXBxhAUJzHHocCuJolwDqql75ZWuCQ_cb33K2vh9m"
          }
      }
    • mitigation :

      • servers should only use a limited whitelist of public keys to verify JWT signatures

  5. Injecting self-signed JWTs via the JKU parameter :

    • some servers let you use the jku (JWK Set URL) header parameter to reference a JWK Set containing the key.

    • create a key

    • attack here to add JKU refer with our server

      • When verifying the signature, the server fetches the relevant key from this URL.

  6. Injecting self-signed JWTs via the kid parameter

  • the header of a JWT may contain a kid (Key ID) parameter, which helps the server identify which key to use when verifying the signature.

    • Verification keys are often stored as a JWK Set , then server may simply look for the JWK with the same kid as the token.

  • If this parameter is also vulnerable to directory traversal and server also supports JWTs signed using a symmetric algorithm

  • In this case, an attacker could potentially point the kid parameter to a predictable, static file

  • then sign the JWT using a secret that matches the contents of this file.

portswigger Labs :

  • 1- JWT authentication bypass via unverified signature

    • the server doesn't verify the signature of any JWTs that it receives.

      1. let’s make a simple get request with Wiener user after login and see the request in burp

    • let’s take a look in JSON Web Token extension

    • change the Sub to administrator in payload and copy the new token

  • let’s make a get request to admin and change the user in inspector from wiener to administrator

  • 3- JWT authentication bypass via weak signing key

    • here we try to crack the hash

      1. login and make a get request to show what we get

      2. server use HS256 algorithm then we know it’s a Symmetric encryption let’s try to crack that token with john or hashcat to get the Secret key with this wordlist https://raw.githubusercontent.com/wallarm/jwt-secrets/master/jwt.secrets.list

    • after we get the secret key ( secret1 )

    • encode the secret key with base64 ⇒ c2VjcmV0MQ==

    • use JWT editor extension & create a New symmetric key and change the value of secret key with c2VjcmV0MQ==

    • back to our request & click sign in JSON WEB TOKEN editor and use our key + change value of payload to administrator

    • make a get request to delete carlos

  • 4- JWT authentication bypass via jwk header injection

    • trick here generate a new key id

    • after login try to see that request

  • let’s try to access admin panel ⇒ we can’t access admin

  • let’s try to create a New RSA Key.

  • then Embedded the new RSA key and verify a request with wiener after change to admin

  • 5- JWT authentication bypass via jku header injection

    • this lab has 2 steps to complete and every one have a many steps : the first one create the key ,, the second is make server Refer to the attacker server to verify the signature

      1. Create and upload a new malicious JWK ( key )

        1. go to JWT Editor Keys and create a new RSA key

        2. but the key in exploit server with this way :

          {
              "keys": [
           new key here 
              ]
          }
        3. put this key in our server and note the link , in this case we have an exploit server

      2. the second step is Modify and sign the JWT

        1. go to our JSON Web Token Extension

        2. In the header of the JWT, replace the current value of the kid parameter with the kid of the JWK that you uploaded to the exploit server.

        3. add a new jku parameter to the header of the JWT & Set its value to the URL of your JWK Set on the exploit server. & change the user in payload to administrator

        4. Sign the new key , then select the RSA key that you generated in the

        5. then we success

Last updated