Now that the deadline to fix this vulnerability has passed, I’ve decided to publish this blog post that covers a web vulnerability I’ve found in the login mechanism of a particular company.
Everything started when I had a look at a more complex part of a public web application of this vendor. The web application that gives out a link to the user that can be used to open up the same user state again at a later point. I’ve then opened this link from a private tab and examined the web requests in the Burp proxy.
The Vulnerability
One link looked particularly interesting, since it contains a redirect_uri
parameter:
https://vulnerable.com/login.html?cl_id=[Some ID]&redirect_uri=https:%2F%2Fwebapp.vulnerable.com%2Fyolo.html&scope=auth&state=ey[Base64]
Parameters like that are often prone to open redirect vulnerabilities that allow attackers to redirect users to another site after they click on a prepared and allegedly trustworthy link. Some web applications don’t check whether this particular parameter has been manipulated and blindly redirect users to the attacker-controlled website after performing a certain action, like performing a login.
What happened is that in fact the redirect_uri
parameter is being sanitized by the web application itself and was therefore not vulnerable to an open redirect attack. I’ve then decided to check out the state
parameter that contains base64 encoded data. Here’s the value of the decoded parameter:
{"request":"new","location":"[somewhere at vulnerable.com]","scroll":"0","configure":true,"additionalParams":{},"locale":""}
Well, what happens after manipulating the location
parameter in the decoded JSON object and putting it back into the login URL?
The web application redirects the user to the attacker-controlled website.
Cool. This affects the central login mechanism of the public customer portal.
The Root Cause
The redirect happens via JavaScript that’s hosted at:
https://vulnerable.com/login/process.html:
let URL = state.oldId ? `${state.location}?id=${state.oldId}` : `${state.location}`;
[...]
document.location.replace(URL)
As can be seen, the redirect happens in the last line of the above listing after the correct URL has been read from the state
parameter. No sanitation is present for this particular parameter, which should be fixed :)
Pls don’t sue