APIs & JWT attacks
Last updated
Last updated
common
Use JSON
Example in Real-world
New
Uses a custom query
Single endpoint control all API
can change in request to get data
and can change anything because can get any parameter the website and change Vale for example password and email
query
mutation => make edited data
How to Test
Less common
Use XML
JWTs are composed of three parts, separated by dots:
Header: Contains metadata about the type of token and the signing algorithm used.
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
is the encoding of { "alg" : "HS256", "typ" : "JWT" }
Payload: Contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.
Signature: To create the signature, the encoded header, the encoded payload, and a secret (or a public/private key pair) are used. The signature is used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn't changed along the way.
Header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Signature: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Purpose: JWS is used to digitally sign the content of a JWT to ensure its integrity and authenticity.
Structure: A JWS consists of a header, a payload, and a signature. The header and payload are JSON objects encoded as base64 and concatenated with a period ('.') character. The resulting string is then signed using a key, producing the signature. The three components (header, payload, and signature) are concatenated to form the JWS.
Use Case: JWS is commonly used when you want to ensure the integrity of the claims within a JWT, proving that the content has not been tampered with.
JWE (JSON Web Encryption):
Purpose: JWE is used to encrypt the content of a JWT to provide confidentiality and secure transmission.
Structure: Similar to JWS, a JWE consists of a header and a payload. However, in JWE, the payload (and optionally the header) is encrypted, providing confidentiality. The resulting encrypted payload is then signed to ensure the integrity of the encrypted content.
Use Case: JWE is used when you want to secure the confidentiality of the information within a JWT especially when transmitting sensitive data
vulnerability that can occur when a system fails to properly validate the algorithm used to sign a JSON Web Token (JWT). In a JWT, the signing algorithm is specified in the header section. If the system does not explicitly define and restrict the allowed signing algorithms, it may be vulnerable to an attacker choosing an arbitrary or malicious algorithm.
Exploitation Steps
Token Creation:
An attacker creates a JWT with a manipulated header that specifies a different, potentially weaker or malicious, signing algorithm.
Token Submission:
The attacker submits the manipulated JWT to the target system.
Token Processing:
The system, if not validating and restricting the allowed signing algorithms, may accept the token and attempt to verify the signature using the manipulated algorithm specified in the header.
Exploitation:
The attacker may exploit vulnerabilities associated with the chosen algorithm, such as known weaknesses or vulnerabilities in the cryptographic library used by the system.
If successful, the attacker could bypass the intended security measures, potentially leading to unauthorized access, data tampering, or other security breaches.
Accepting Tokens with No Signature attack, also known as an unsigned token attack, occurs when a system does not enforce the presence of a digital signature in JSON Web Tokens (JWTs) during the authentication or authorization process. In a standard JWT flow, the digital signature is crucial for ensuring the integrity and authenticity of the token. However, if a system mistakenly accepts unsigned tokens or fails to verify the signature, it becomes vulnerable to various security risks.
Exploitation Steps
Token Creation:
An attacker creates a JWT with the "alg" parameter set to "none" in the header, indicating that the token is unsigned.
Token Submission:
The attacker submits the unsigned JWT to the target system.
Token Processing:
The system, if not properly configured or secured, accepts the unsigned JWT without performing any signature verification.
Exploitation:
Since the system accepts the token as valid without signature verification, the attacker gains unauthorized access or manipulates the information contained in the token.
Consequences:
The consequences may include unauthorized access, data tampering, and a compromise of the integrity and authenticity of the information conveyed by the token.
Even if the token is unsigned, the payload part must still be terminated with a trailing dot
Example
Some signing algorithms, such as HS256 (HMAC + SHA-256), use an arbitrary, standalone string as the secret key. Just like a password, it's crucial that this secret can't be easily guessed or brute-forced by an attacker. Otherwise, they may be able to create JWTs with any header and payload values they like, then use the key to re-sign the token with a valid signature.
Brute-forcing using hashcat
or Using John
Interesting Headers :
jwk
(JSON Web Key) - Provides an embedded JSON object representing the key.
jku
(JSON Web Key Set URL) - Provides a URL from which servers can fetch a set of keys containing the correct key.
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. Depending on the format of the key, this may have a matching kid
parameter.
JWK (JSON Web Key): It's a standardized format for representing cryptographic keys as JSON objects. In the context of JWS, the JWK format can be used to represent public keys.
Public Key & Private Key
Signature Key:
The server uses its private key to create the digital signature for the JWT
Signature verification
The recipient (server or client) uses the public key to verify the digital signature. This involves decrypting the signature with the public key and comparing it to a recalculated hash of the message. If they match, the signature is valid.
2. Send a request containing the jwt header to the repeater and go the the JSON Web Token tab from the attack menu embed the created JWK and change the username
python3 jwt_tool.py JWT_HERE -X i
Instead of directly including public keys through the jwk header parameter, certain servers enable the use of the jku (JWK Set URL) header parameter to point to a JWK Set containing the relevant key. During signature verification, the server retrieves the necessary key from the specified URL.
A JWK Set is a JSON object containing an array of JSON Web Keys (JWKs), allowing for centralized key management. It is commonly used in JWT-based authentication systems to provide a set of keys for signature verification.
Example
JWK Sets like this are sometimes exposed publicly via a standard endpoint, such as /.well-known/jwks.json
1. Generate Self-Signed Key:
Using burp jwt Editor
Get the JWK
right-click on the entry for the key that you just generated, then select Copy Public Key as JWK.
Hosting
Host the self-signed public key as a JSON Web Key (JWK) Set on a server or accessible location.
Changekid
value
In the header of the JWT, replace the current value of the kid
parameter with the kid
of the JWK that you uploaded to your server.
Add jku parameter
Add a new jku
parameter to the header of the JWT. Set its value to the URL of your JWK Set on the server.
At the bottom of the tab, click Sign, then select the RSA key that you generated.
Make sure that the Don’t modify header option is selected, then click OK. The modified token is now signed with the correct signature.
Ruby library Net::FTP (CVE-2017-17405)
Exploit
Scenario:
The application uses the "kid" parameter to retrieve a secret key from a database for signing JWTs.
An SQL injection vulnerability in the "kid" parameter allows an attacker to manipulate the SQL query and retrieve a known secret.
Example:
Suppose the JWT header is as follows:
Normal SQL Query:
Exploited SQL Injection:
Exploitation Steps:
The attacker identifies an SQL injection vulnerability in the "kid" parameter.
Instead of a legitimate "kid" value, the attacker injects malicious input
The attacker sign a new JWT with the same value as the secret in the SQL query
When the attacker sends the tempered JWT to the server the SQL query will result kid=secret_123
as zzz
is not exist
As the kid value matches the key that the token signed with the attacker will be able to send a valid token
Asymmetric (RSA)
Private key
Public key
Symmetric (HMAC)
Shared secret
Shared secret
JWTs can be signed using a range of different algorithms. Some of these, such as HS256 (HMAC + SHA-256) use a "symmetric" key. This means that the server uses a single key to both sign and verify the token. This needs to be kept secret, just like a password.
Other algorithms, such as RS256 (RSA + SHA-256) use an "asymmetric" key pair. This consists of a private key, which the server uses to sign the token, and a mathematically related public key that can be used to verify the signature.
As the names suggest, the private key must be kept secret, but the public key is often shared so that anybody can verify the signature of tokens issued by the server.
'none' Algorithm (CVE-2015-9235):
Step 1 - Obtain the server's public key:
Servers may expose their public keys as JSON Web Key (JWK) objects through endpoints like /jwks.jso
n
or /.well-known/jwks.json
.
Extract the public key from a pair of existing JWTs if not publicly exposed.
Step 2 - Convert the public key to a suitable format:
The server's public key may be in JWK format, but for the attack to work, it needs to match the server's local copy.
Assume the key needs to be in X.509 PEM format and convert a JWK to PEM using the JWT Editor extension in Burp:
In Burp's JWT Editor Keys tab, click New RSA Key, paste the JWK, select the PEM radio button, and copy the resulting PEM key.
Base64-encode the PEM in the Decoder tab.
Go back to JWT Editor Keys, click New Symmetric Key, generate a new key in JWK format, and replace the value for the k parameter with the Base64-encoded PEM key.
Step 3 - Modify your JWT:
Once the public key is in the right format, modify the JWT as desired, ensuring the alg header is set to HS256.
Step 4 - Sign the JWT using the public key:
Sign the token using the HS256 algorithm with the RSA public key as the secret.