Recently I saw a vulnerability that was very new to me. I've seen authN and authZ tied to some super random things in the past; ad tracking IDs, the literal username in a header, etc, but this one takes the cake for being weird to spot. It also highlights why the headers and their values need to be interrogated for both requests and responses.
Starting the test there was a previous instance of an IDOR related to accessing uploaded files. The original vulnerability was pretty bad as it allowed unauthenticated users access to sensitive customer financial documents (pdf, png, jpeg). Following the previous instructions, they were easy to access as all you needed to do was browse directly to them. I did so, and it failed. So vulnerability remediated right? Nope.
HTTP Request & Response:
GET /random/file/name/39439202.pdf
Cookie: SessionID=ewjnefkn24948hf94hf983; // Secondary user session
----
302 Found
Location: /home
I wanted to try one more thing just to see how it worked between sessions, so I grabbed a random request from my Burp Proxy and threw it in Repeater. Modifying that request to point to the affected endpoint, I then sent it and got back the PDF. So it works as expected, as I currently have a valid session cookie for that user (along with some other cookies). At that point I started removing cookies and resending the request, one cookie at a time. This was just to see if it would have any previously unseen affects on the request. But then I got down to zero cookies, and the request was still succeeding... what?
HTTP Request & Response:
GET /random/file/name/39439202.pdf
Cookie:
Referer: qa.example.com/test?val=fin3283nddmwfo4hfw8f4pif4lwn4fjnw
----
200 OK
PDF 1.7
Sending the failed request that had another user's session cookie in it, and the request with zero cookies in it into comparer showed that the main difference between the two was the presence of the referer header. At first I was a little scared, not sure if it would still be valid as the referer header had a huge randomized string attached to the end of it that looked random. Deleting this string and just leaving the base URL (qa.example.com) I resent the request, and the PDF was still accessed. Removing the URL and putting a different domain into it (google.com) broke the request. So it was official, they had tied authorization for the endpoint to the presence of a referer header with their domain inside of it.
HTTP Request and Response:
GET /random/file/name/39439202.pdf
Cookie:
Referer: qa.example.com
----
200 OK
PDF 1.7
So the general advice for today, is to not tie your application's authorization to random headers. Whether it's a cookie, JWT, or API key, please only utilize that. What's the point of doing all the hard work of implementing authN and authZ systems just to not use them?
To Remember:
Always check every header and its value. One by one.
Always identify what is and isn't related to controlling authN and authZ. Study the login flow too.
If something is acting suspiciously, don't slam random payloads into it. Experiment with it piece by piece. Slightly change one thing, send the request, observe the response, then slightly change another.