Isn’t business continuity part of security?
Andrea Covello
How signed JSON Web Tokens can be compromised
A JSON Web Token (JWT) is an access token that meets the RFC 7519 standard and transfers information between different parties in the form of a JSON object. The token contains the required information, which is why it can be used to authenticate or transfer information between the front-end and back-end, for example. The content of the token is base64url-encoded and the information contained in the JWT is therefore available in plain text. It is possible, however, to verify and sign the JSON Web Token to prevent manipulation of the token.
A signed JSON Web Token has three sections: The JOSE header, the JWS payload and the signature. Each element is separated by a period .
.
Example of a JSON Web Token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InNjaXAgQUciLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNTE2MjM5MDIyfQ.dX_ACtDZVh9ZKaDMLmZFURrh7o5R99-6MEulWUFCaT0
The JWT example decodes:
{"alg": "HS256", "type": "JWT"}
{"sub": "1234567890", "name": "scip AG", "admin": true, "iat": 1516239022}
dX_ACtDZVh9ZKaDMLmZFURrh7o5R99-6MEulWUFCaT0
(uses the scipAG
secret)The first part of a JWT is the JOSE (JavaScript Object Signing and Encryption) header. It contains information about the algorithm used to sign the token. For example, a token can be signed with HMAC algorithms and a secret or using a public/private key method, such as RSA or ECDSA. All usable algorithms are described in the specification JSON web algorithms (JWA).
What is striking here is the algorithm is set to none
. This means that it is possible to hack a JWT by setting the algorithm to {"alg":"none"}
and removing the signature. If the back-end does not carry out any signature verification, the manipulated token can be readily accepted. That’s why it is essential to verify the signature. Otherwise, the information in the token’s payload can be changed to anything. For instance, changing the user role can help to achieve a privilege escalation.
The second section of the token – the JWT claims set – is a JSON object that contains the information (claims) to be transferred. There are three classes of JWT claim names:
The names must always be unique. The predefined claims are explained in RFC 7519.
The JWS payload is also base64url-encoded, so it is important that no sensitive personal data is sent with a JWT, for example. Otherwise, an attacker can analyze a JWT to find this information, determine the structure of email addresses or usernames, or discover the exact designation of user roles. This is because signing the token merely prevents manipulation of the same – the information it contains is basically always visible in plain text. Making changes to a JWS payload is simple. Burp Suite, for example, offers various extensions, including JSON Web Tokens (JOSEPH) to help with this task.
The third and final element of the token is the signature, which has an RFC 7515-compliant structure. The signature is also base64url-encoded and is created with the selected algorithm from the JOSE header. The signature is designed to prevent a token from being manipulated during transmission.
The signature of the JWT can, however, be vulnerable as well. If the HS256 algorithm is selected and a weak secret used, the secret can be cracked. Hashcat in particular includes a function for this purpose (hash mode 16500).
./hashcat64.bin --session <project> -a 16500 -m <jwt> -w 3 -r <rulepath> <dictpath>
As soon as the secret has been figured out, the token can then be manipulated or regenerated at will and signed with the corresponding secret. An online JWT generator can even be used for this purpose.
In general, there are access tokens and refresh tokens. If the validation of access and refresh tokens is not configured correctly, under certain circumstances it may be possible to refresh an access token (including an expired one) belonging to another user with your own refresh token if the hacker is able to get their hands on it. This can be done if only the validity of a refresh token is verified rather than the ownership of the access token.
The conditions for the request are based on the information about the endpoint where a new token is generated, an Authorization: Bearer
header with the access token that has expired, as well as the refresh token in the body of the request.
Example of refreshing an unknown access token with one’s own refresh token:
POST /scipAG/JWT/refresh/newToken [Various Headers] Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InNjaXAgQUciLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNTE2MjM5MDIyfQ.dX_ACtDZVh9ZKaDMLmZFURrh7o5R99-6MEulWUFCaT0 [Various Headers] {"refresh_token": "thisIsAnExampleOnly"}
Compared to SAML (Security Assertion Markup Language), a signed JSON Web Token has the advantage that it is easy to implement, since it is small enough to easily fit into an HTTP header. Conversely, it is not possible for a JWT to completely replace an SAML. SAML 2.0 offers more security options, but these involve greater complexity and scope. The use of XML, XML digital signature (DSIG) and XML canonicalization are reasons why SAML is so complex.
Compared to simple web tokens (SWTs), a JWT offers greater flexibility and more options. While both claim names and claim values are strings in the case of an SWT, the claim values of the JWT can assume any type of JSON. Moreover, SWT only supports HMAC SHA-256, while JWT lets you choose between different algorithms.
Signed JSON Web Tokens are secure as long as they are configured correctly and carefully. However, it is important to ensure that no sensitive information, such as the username, user role, etc., is sent with the token, because this data is only base64url-encoded and is not encrypted during transmission.
Our experts will get in contact with you!
Andrea Covello
Michèle Trebo
Lucie Hoffmann
Yann Santschi
Our experts will get in contact with you!