Drilling the redirect_uri in OAuth

I’ve been hunting for several years as a part-time hunter and have discovered many vulnerabilities. My most focused area, and my favorite, is the authentication class, which includes sign-up, sign-in, forgot password, 2FA, account deletion, etc. Nowadays, most websites have OAuth authentication beside normal credentials login, and many newcomers skip the OAuth.
It’s reasonable since OAuth has a pre-defined standard implementation that ensures security by containing best practices. You may find many vulnerabilities in laboratory environments such as PortSwigger’s. The main misconfigurations are
Manipulation of the
redirect_uriparameter to steal the OAuth token. This is due to the provider; in many cases, the providers are safe enough because they have been tested many times, such as Google, etc. Roughly ten years ago, as far as I remember, the first time Nir Goldshlager found the flaw in Facebook’s OAuth redirect-uri quirks, which made any website using Facebook as the provider vulnerable. Even after the fix had been issued by Facebook, he managed to bypass the patch. It was a fantastic finding at the time.Chaining the Open Redirect with a legitimate
redirect_urito steal the OAuth token. This is not the provider's fault, since they securely check theredirect_uriand redirect the user back to the right place, but the Open Redirect breaks the security.
However, in the second case, the state parameter ensures that the flow is safe. Despite having an Open Redirect on a website, the state parameter does not allow an attacker to steal users’ OAuth tokens. You may ask why? Since the state parameter value is bound to the user session, the attacker cannot trick the user to grab their token as well. Almost all OAuth authentications have a state parameter, so as a hunter, should we give up testing OAuth logins? The answer is NO :)
Attacking Scenarios
There are many attack vectors against OAuth logins depending on the setup. I’m not going to go through all of them, but I will discuss a case I’ve encountered several times, even in famous public HackerOne programs that I cannot name right now. Let me list three of them:
Capability of
redirect_urimanipulation → Provider’s flawChaining
redirect_uri+ open redirect + lack of state check → website’s flawCapability
redirect_urimanipulation + lack of state check → website’s flaw
But wait a minute, the third one is not possible since redirect_uri checks are applied by the providers. Yes, you are right, so let's keep reading.
Different Flow
As mentioned, OAuth has a fairly standard and secure implementation. However, due to scalability or other factors that I do not even know, companies decide to alter the normal flow. This "out of normal" always needs double security checks, not only in OAuth but also in other technologies, such as login, 2FA, etc. The normal and simplified flow is something like this:

The authentication factor (Cookie or JWT) is issued immediately after the user is redirected back from the provider, using the code. Another pattern which I see, mostly in Application logins (not the web applications) is to extend the flow:

Here, as observed, there is an in-between phase before the authentication token is issued. An in-between redirect, honestly, I have no idea what it is for; maybe they have multiple channels for different platforms (Mobile, App, Web, etc.).
The Vulnerability
In the previous flow, if the state value is not properly checked and the second redirect URL is controllable by attackers, the OAuth system will be vulnerable, matching the third bullet point in the attack scenarios. Let me bring an example from one of my reports. During the hunting, I reached an OAuth in a MacOS application. The initial URL just after clicking on the “Login with Apple” button was:
https://www.redacted.com/lvpc_web/apple_auth
?login_id=95812a37-cb82-4789-bc73-dbe5f1079274
The response was a 301 redirect to the following URL:
https://appleid.apple.com/auth/authorize
?client_id=com.redacted.web
&redirect_uri=https%3A%2F%2Fredacted.com%2Flv%2Fv1%2Fcallback%2Fapple%2Flogin
&response_type=code%20id_token
&state=%7B%22platform%22%3A%22apple%22%2C%22id%22%3A%2295812a37-cb82-4789-bc73-dbe5f1079274%22%2C%22redirect_uri%22%3A%22https%3A%2F%2Fwww.redacted.com%2Flvpc_web%2Flogin_status%22%7D
&scope=name%20email
&response_mode=form_post
&frame_id=28f353fe-1c0e-4be6-b95a-3141f07b7f16
&m=11
&v=1.5.5
The redirect_uri in the query string is completely safe (the provider is Apple), and there is no attack here. Let’s take a closer look at the state parameter:
{
"platform": "apple",
"id": "95812a37-cb82-4789-bc73-dbe5f1079274",
"redirect_uri": "https://www.redacted.com/lvpc_web/login_status"
}
Here is the second redirect_uri, which is entirely outside the OAuth protocol. The parameter name could have been different, like rPath, and the value could also have been relative, such as /lvpc_web/login_status. Fortunately, my tests proved that the backend was not checking the state parameter. So I changed the redirect_uri to the illegitimate URL https://attacker.com and got a mismatch error. Here, I did some magic with @ and found out that https://www.redacted.com@attacker.com/ is acceptable, which allowed me to discover a one-click Account Takeover using a basic trick and some careful observation. If the URL were relative, I would definitely try to convert it into a full URL and add some tricks. As the state wasn't validated, I could craft a malicious link by setting the second redirect_uri parameter to my domain using the at-sign trick.
Final Words
Chasing the root cause, we will end up with "outside normal behavior" or "custom implementation". I discovered many vulnerabilities due to this root cause. In the example above, the programmer modified OAuth by adding an extra step. They used the state parameter to store data in a way it wasn't meant to be used, and on top of that, they didn't properly check the state value. So, if I want to end this post with some tips, they would be:
Check every OAuth channel one by one; do not skip any. If the target has "sign in with [several providers]," check all of them
If the program has a mobile or application, apply the previous steps to them too
Look for odd changes made by programmers. If there is a custom section, pay extra attention to it, as they might have overlooked security there

![uXSS on Samsung Browser [CVE-2025-58485 SVE-2025-1879]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1769612322324%2F5d0547d4-f91a-49d7-bc16-70a87513b506.png&w=3840&q=75)


