Today I'll share a quick article about the nicest open redirect issue I've ever found.
It wasn't even paid yet, but was already validated by the triage team. I'll update this article if it awards a bounty.
Recon
First of all, I've done a very wide recon on this target, which is an open-scope program (those have been my favorite ones).
After doing a TLD brute-force and checking for related domains (check my TLD list), I've found an interesting domain. It had many files with the .do extension. One of the files was checkSession.do.
Inside it, there were the following two JS snippets:
if (isNotEmpty(redirectUrl)) {
if(!redirectUrl.startsWith('//') && redirectUrl.indexOf('.do') > 0 && (redirectUrl.startsWith('/') || redirectUrl.startsWith(location.origin))){
location.replace(redirectUrl);
}
else{
alert("Invalid URL.");
location.replace("/app/login.do");
}
} else {
location.replace("/app/main.do");
}
}By reading it, we can notice that the parameter redirectUrl exists, and the contents of it must:
- !redirectUrl.startsWith('//') — not start with //; my PoC starts with https://
- redirectUrl.indexOf('.do') > 0 — have .do in it; my PoC has /x.do
- redirectUrl.startsWith('/') — start with / or:
- redirectUrl.startsWith(location.origin) — and start with the location.origin; my PoC has it
And this one:
var check = '<check-parameter-contents>';
var redirectUrl = '<redirectUrl-parameter-contents>';
if (check == 'login') {
redirectUrl = "/app/login.do";
}
else if (check == 'agree') {
redirectUrl = "/app/login/policy.do";
}All I had to do was to fulfill the redirectUrl requirements and instead of using an existing location for the check parameter, I've used an x.
That said, the crafted PoC looked like this:
In less than 10 minutes it was validated by the triage team. Let's see if it will be paid:

Lessons learned:
- Always read the HTML; It usually leaks vulnerable stuff and handcrafted code that contains vulnerabilities;
- Manual analysis for simple and complex bugs is always worth it and can still be profitable.