JWT authentication bypass via jwk header injection
Description
This lab uses a JWT-based mechanism for handling sessions. The server supports the jwk
parameter in the JWT header. This is sometimes used to embed the correct verification key directly in the token. However, it fails to check whether the provided key came from a trusted source.
Reproduction and proof of concept
In Burp, load the JWT Editor extension from the BApp store.
In the lab, log in to your own account and send the post-login
GET /my-account
request to Burp Repeater.In Burp Repeater, change the path to
/admin
and send the request. Observe that the admin panel is only accessible when logged in as the administrator user.Go to the JWT Editor Keys tab in Burp’s main tab bar.
Click New RSA Key.
{
"p": "8ehx1gw1ogk_7A91WcOc2ZKiS2wel5QsyRXjltp_c8cMR687OEuB8DKR6B7LP7IIc5e1oJ3Vs_V1II63fSGlnMP4jmTwO6ENQmILr4gfrJp2x_KcJLnejeFL3T1EMDtkAgbDKgnijFqnlHfBUiHE_o0k5Nymrcg3dL7HBeZv9NU",
"kty": "RSA",
"q": "628XhjPi2xfpdw3aNT3TLWvXrsb2rJMn5dPVXC6BB7nKPVwv2eAXTOw4JWgcfye7_1vuIOZr3x-TA8sjyTT25tViYIXqPuj6tGRx4soTwjJc3UdwL4vPXCFpO9wmQIckuFzTh1_hjXpHFhLiF_3TcgxKLP4g3ZV7ELZ4lCunNGk",
"d": "AzA7jRuWGB7xz8_AupKhVWZH6ZyS-OBOGUTHApBqheDTaVvELdGvDe55M8YTK8EwZ5nBGgGcSf0coYqPdIRuOkMxWIfPGFJ3274mueBo_Qrf6JASyD8JH8am2e8eeg9GqxG19RwwZ4U9GdaMJKiyi2tDL96BjW8C-NRNyv-GSuuoF0PTXCq0ibaootnWmTXYCHJQ1w4qEiKVjv-e74pS8-v0CwrzUUJV-gXrnzs8e35m0bnWWjLbmzhlExDhfcfbFcBc-64hl4799djt19Zq_waHhAGdTK5XpAAsjtd98GfkymWwWfM1RIHyKKnDp3fxGdpet8TPUEHuILIiADmY6Q",
"e": "AQAB",
"kid": "9a1a93f9-0f9a-4f33-991c-06a5885a3500",
"qi": "YU_yELxttfS0LZJCk3IOnF_v5faOZn_Ftv6Aa1Rl7XqzfrWAzDGbyrto_SUfnzBtw8rMARtLXGbHbdK6R3i4q_7g6nwB8WnMJVmlcPyAlUUt_mEX7f2fNVhUPnFQaW3od5ZPBsqk74NYCXqy-zSVxYeCUeCnuTHxRvrg0RsUrac",
"dp": "VJn-deV_PFQPzvb5C5Ol31GxAL-nU0u2_fxxw-hWep86ZDecdmux3ddRv-RFINmaqxJ7qtiITI-jjudatKB30wOWgfY7Lh99C6JOg-0PZsX-lJ78jLuUYfpRFea_Wj7rEupahvE-EegCg6H-MkMtKfki1gd1I4HKI0I1SJL2xKE",
"dq": "56_lqI37G70GZcDeEjMLVNGh6T-nlOEkDEpQ12x0UhQF8Ch-dpzOkUaNYlJ4aLHDkmL3jqzzTxoVZVBNoT5cE4G-VFq00MAZp9iJMrPGif9h3-jjgAbIQ1Ql6WCWzD2yZzQCfmBe6QmCVziyAwYpRTzO6kQUN7tY5nOLadUjsLE",
"n": "3nlag4vyBQ2KmOwusjblF8_XodPeU1eNaNU3Wqxqpn3dTJGxQQkqEtBoLzphZJqVcNBs9Tk_36zEJapHkU9zAQAY__lbRkTevL-8acoiDotmZYXaELZxMktCu2Ae2QZmKsI0aye6sO3XAD6u5vMKdQLSljtlcXg9jgJ8gUdr2ZATJpb0RHlwXYTKE2xvm0fkL5BWSfqod-n2JCq5bt-ARZljlkjlHn1MNXOfl1s7Z3dDoSpaS42iGBkwZqeSj_FyhndpTsbtvyJ5shYwEYohCZ02k_WnaiwyMhT8fCnaR7OBTJ67rAOHqcpBxdShLOiosLrKwTwV2AGIJliGv5mvXQ"
}
In the dialog, click Generate to automatically generate a new key pair, then click OK to save the key. Note that you don’t need to select a key size as this will automatically be updated later.
Go back to the
GET /admin
request in Burp Repeater and switch to the extension-generated JSON Web Token tab.In the payload, change the value of the
sub
claim to administrator.
At the bottom of the JSON Web Token tab, click Attack, then select Embedded JWK. When prompted, select your newly generated RSA key and click OK.
In the header of the JWT, a
jwk
parameter has been added containing the public key.
Send the request. Observe that you have successfully accessed the admin panel.
In the response, find the URL for deleting Carlos (
/admin/delete?username=carlos
). Send the request to this endpoint to solve the lab.
Exploitability
An attacker will need to log in to wiener:peter
; modify and sign a JWT that gives access to the admin panel at /admin
; then delete the user carlos
.
Instead of using the built-in attack in the JWT Editor extension, you can embed a JWK by adding a jwk
parameter to the header of the JWT manually. In this case, you need to also update the kid
header of the token to match the kid
of the embedded key.