Unvalidated redirects and forwards are possible when a web application accepts untrusted input that could cause the application to redirect to a URL contained within untrusted input. This makes it possible for an attacker to redirect the browser to a malicious site and use trusted domain name to gain the victim’s credence.
Unvalidated redirects and Unvalidated Forwards are two different vulnerabilities of same class. This vulnerability was one among the OWASP Web Top 10 in 2013 but not found in 2017’s Top 10 list.
While testing unvalidated redirects, I have encountered 2 common scenarios
- Straightforward redirections
- Tricky redirections
As the name itself suggests, this class of vulnerability can be found in the scenarios where, giving a URL as an input to a parameter will directly perform redirection.
HTTP 1.1 302 Found
Important pointers while testing:
- Each and every parameter can be vulnerable. So don’t just blindly look for the parameters which contains “URL” string
- Parameters such as callback, next, go, redirect, return, back etc can also be vulnerable
- Don't forget the first point. Each and every parameter can be vulnerable. Parameter “q”(in above URL), a Referrer header, a random key in cookie, anything can be vulnerable to redirection attack.
In a few cases, it’s tricky to identify the payload which performs redirection.
A simple payload, https://www.example.com/path123?q=dontforgetethics&url=https://www.attackers.com might not work sometime.
There could be validations present on whitelisted domains, protocols, paths, patterns etc. In those cases, a little effort will be needed to find the bug. Though there are a lot of ways to bypass such validations, a few would be:
(incase http:// is blacklisted)
(incase // is blacklisted!)
(useful for bypassing blacklists // and http://. Browsers see /\/\ as // )
(old but gold, browsers will redirect to anything after ‘@’)
(when there is a validation on whitelisted domain after the first occurrence of ‘@’ symbol)
(when there is a validation on the domain after last occurrence of ‘@’ symbol)
(Beauty of ‘\’)
?url=https://whitelisted.com%00attackers.com (Null Byte, depends on context)
This is not an exhaustive set. These are few of the tried and tested payloads I remember. There are many more to these. Keep reading and keep trying.
So one fine day,
I was testing a website in one of the bug bounty platforms. Let's call the domain as
Though I always try for XSS, IDORs and other business logic bugs, for my bad luck I couldn’t find any. I also tried for redirection vulnerability in multiple URL parameters. In few APIs it was whitelisted properly(I tried my best to bypass) but in few it was a dummy parameter(no significance of URL parameter. That hurts!)
While testing I encountered an API path,
I tried to understand the significance of each parameter and tampered it accordingly, but nothing seemed spicy! Each wrong tampering redirected me to the error page
Continuing, I changed the parameter “lang” to “xlang”. To my surprise, I got a 302 redirection for a new path which I had not seen before.
I was happy as this was a new path containing new parameters and also URL seemed to belong to first category of redirection(Straightforward)
For this URL,
Response was something like this:
I tried different payloads of XSS with respect to the reflection context. As XSS is out of scope for this article, I will write about beautiful problems one could face while identifying XSS in coming articles.
For redirection vulnerability to work, I tried Straightforward payloads such as,
Err!! Payload was reflecting as path parameter!
Multiple attempts were performed such as giving IP addresses, null byte, encoded URLs and all tricky known payloads. But no luck!
Then I started combining different characters %0d, %0a, %00, %08, %03, %0E, etc with different payloads and observed the behaviour. Finally it was %09 which made a difference.
Note that %09 is horizontal tab and hence non-printable (there is a space before ‘/@’). But when it got executed inside the script, it did its magic.
The same vulnerability was present in other subdomains as well and hence, I reported a redirection vulnerability on the “go” parameter for multiple subdomains.
I would say, the turning point is the “lang” parameter. If “lang” parameter is not sent, then the application redirects the user to a whole new path. Luckily, the parameter in that new path was vulnerable to Redirection attack. So remember, Each and every parameter can be vulnerable. So keep fuzzing!
Crash the clap button if you liked this article 😉