BOOK THIS SPACE FOR AD
ARTICLE ADMy take on Open Redirects with some great insights from Vickie Li’s new book :)
Open Redirects are those low hanging bugs you look out for as a bug bounty hunter. Because why not! They’re quite easy to discover and don’t require that much brain work right! Or is there more to them?
So I was just exploring Vickie Li’s new book focused on Bug Bounty Hunting and found that there was a FREE chapter. So took that opportunity to explore it and see if the chapter is something different from what we typically find in those bug bounty blogs or Youtube videos. And believe me, it was quite a awesome read — time worth spent, I must say!
The chapter didn’t only introduced the topic but Vickie went ahead and explained a lot of stuff, especially the root cause of not being able to fix this issue properly — Parser Differential attacks!
She also covers on the different ways of tricking the URL validators to accept the attacker-supplied URL and carry out the attack! And I must say, she did a quite awesome job of explaining things and putting everything in an organized manner!
Ever seen a website redirecting you to another URL or location specified in the URL itself?
Like https://supersecuresite.com/login?next=dashboard
Or https://supersecuresite.com/login?next=https://supersecuresite.com/dashboard
But why do they do so? Because let’s say you are surfing twitter and found out my amazing website. But sadly when you land onto that page, you get redirected to the login page, before you can continue with that website. And once you login, now the good user experience rule suggests that the website would take you back to the page you came for! And in order to do that, the website has to remember your last page, that you visited. Then it can redirect you to that page, once you successfully login.
But what’s Open Redirect? It is a bug where the backend redirects the user to ANY website specified in the URL, without proper filtering!
So what’s the issue here? Looks like things are done as they should be, right? Or are they?
What if the redirection URL parameter was tampered with? Will the site redirect you to whatever it finds in the redirection parameter? Or will it validate things before proceeding (like it should)? And can this process still be influenced by the attacker, even after the server does checks before redirecting the user? Let’s find out!
But what’s Open Redirect? It is a bug where the backend redirects the user to ANY website specified in the URL, without any filtering, whatsoever!
In the book, Vickie explains that there are 2 types of Open Redirects:
Vanilla Open Redirects (which are just called “Open Redirects”)Referrer-based Open RedirectsBut if you notice, its just 1 attack class, where the URL input is not validated. The positions where user injects the payload changes: in first case its in the URL parameters, making it a parameter tampering attack and in second case, its the header, so that would be a header injection attack! But again, the root cause is still the same — trusting user-input to redirect!
So now that we know the root cause is trusting user-input to perform a redirect, can’t we easily get rid of it? Must be easy to just validate the user input right? Just do a check if the URL matches what we expected and then off we go… Or wait, can a user potentially bypass our checks?
Well, as it happens that the URL structure is difficult to parse and different parsers give different results on what they think are the different URL parts.
So, a URL looks like this:
scheme://userinfo@hostname:port/path?query#fragment
Now if you ask different parsers, they might end up seeing the hostname and port differently from other parsers! Why? Because some parsers try to correct user mistakes while others don’t and thus there is this “parser war” if you will, to provide the most flexible implementation to you, even if that means things will be inconsistent with other URL parsers. And that brings us to the point I mentioned at the very start: Parser Differential is the main reason this issue is hard to fix! Different parsers see the same URL differently and thus some might consider one hostname, while others might consider another hostname, all depending on how the parser see’s the URL!
Take this URL for instance:
https://user:password:8080/example.com@attacker.com
What should the browser make out of it? And what the parser used in different programming languages make out of it? Turns out that this confusion is the source of all the chaos!
1. Browser Autocorrect:
Take these 4 URLs for instance and try opening them in Chrome, Firefox and Edge (or Safari if you are on Mac):
- https:attacker.com
- https;attacker.com
- https:\/\/attacker.com
- https:/\/\attacker.com
What do you see?
It turns out that Chrome and Edge treated all of the above URLs as https://attacker.com and Firefox treated all but the second URL as https://attacker.com
So, it shows that if different browsers can’t agree on those URLs, you can imagine if you start checking the different library implementations, like for Python, Go, etc. you will definitely find out the differences in how the different URL parts look like!
Browsers also autocorrect the \ in the URL and convert it to /:
Ex: https:\\attacker.com is seen as https://attacker.com
And using that logic, if you pass: https://attacker.com\@example.com
The resulting URL would be: https://attacker.com/@example.com
You see where I am going with this?
Between the scheme and the @ character, the domain name is present. But if there is a path separator ( / ) then, the @ becomes the part of the path!
So in the first case, the userinfo is attacker.com\ and the domain is example.com
But in the autocorrected URL, the domain is attacker.com
And that’s why I mentioned that its hard to fix these issues due to parser differential!
Plus here you saw an interesting thing: Mutation of the URL leading to open redirect! (reminds me of mXSS!)
Okay, fine but what if we check that the URL which we are redirecting to begins and ends with the URL we want to visit! Won’t that fix the problem?
Nope, it won’t :)
Consider the following 2 redirect URL examples (from the book), where we bypass the URL validator checking for the beginning and ending being marked by the benign site we want to redirect to i.e., “example.com”:
http://example.com.attacker.com/example.com
http://example.com@attacker.com/example.com
The attacker can create a subdomain (the front part) on their domain and create a folder for example.com (the end part).
Or the attacker can just create the folder for example.com (the end part) and pass the initial check by just leveraging the userinfo part!
Data URLs can be used to run arbitrary JS and they can contain base64 encoded data, essentially tripping-off the validators and bypassing all the checks… Straight and sweet right ;)
Ex: data:text/html;base64,PHNjcmlwdD5sb2NhdGlvbj0naHR0cHM6Ly9hdHRhY2tlci5jb20nPC9zY3JpcHQ+
Type it in the address bar of your browser and see where it goes ;)
A validator might decode the URL multiple times thus springing the parser differential problem leading to different parser seeing things differently leading to a sweet bypass again :)
Sometimes the browsers decode non-ascii characters as question marks and sometimes those characters might be replaced with a similar looking character. But don’t think this is the case anymore and it looks a bit weird since that is not the case anymore. And I have tried the payloads mentioned in the book for those sections without any success :(
So I think multiple encoding is something I would definitely agree on, but the Non-Ascii Characters part didn’t worked for me in 3 major browsers: Chrome, Firefox and Edge. Feel free to try and leave comments, but I think that part is not valid anymore and maybe it gets revised in next edition hopefully :)
With all the above tricks in your arsenal, you can pick those and combine them to bypass the validators. Fuzzing might definitely help to see the perceived URLs by different validators, helping you craft a payload to successfully uncover this bug!
Afterall Open Redirects can only lead you to a attacker controlled page, what next?
Phishing would be easiest answer I suppose!
But wait, there’s more! Clickjacking (by embedding the website in an iframe and overlaying the login form with a transparent layer, recording all the keystrokes!). But, its still too lame right…
What about SSRF?!
If a website is vulnerable to this attack, an attacker can circumvent the URL validator and access internal IP like localhost for instance or the link local IP in case of an EC2 instance and exfiltrate the instance metadata: userdata script and instance profile at the very least!
These are some of the easy wins, that I could think at the top off my head and were mentioned in the book as well :)
I realized that its getting a rather long post now and I should stop…
So my take on this book: Bug Bounty Bootcamp would be (based on the only chapter I read) that its well written and quite comprehensive. Except a few mistakes (outdated attack vector for Unicode stuff, which is like a thing of past), I don’t have any complaints. The book is quite beginner-friendly and lists all the techniques you should use when hunting for Open Redirects! It’s like a cookbook style thing where you go and pick up the payload and follow through, to see your next steps. Quite impressive work there :)
And what I like is that as the chapter ends, Vickie gives the summary of the steps so you can build a mental model at the end! Nice work overall :)
I hope you enjoyed this post on Open Redirects, adding in my insights with the stuff from Vickie’s books and reviewing things all along :)
I will see you next time with another interesting post.
Btw if you are enjoying my work and would like to support me, then please check out my Patreon page: https://www.patreon.com/SecurityGOAT
See ya!
Until next time, keep learning and happy hacking :)