In this article, we will go through the most common security vulnerabilities encountered in applications that use the OAuth protocol. The protocol itself is reliable but it relies heavily on the web developer awareness when implementing authorization, which makes this topic extremely important for developers to keep their user’s accounts and data secure. We will expose best practices to help mitigate the danger of bad OAuth implementation.
Note: This article requires a basic understanding of the OAuth 2.0 protocol. You can refer to this Introduction to OAuth 2.0 where I explain the protocol in details. To further familiarize yourself with the protocol, you can apply the theoretical concepts by referring to the following practical tutorials:
The OAuth 2.0 protocol is heavily used in third-party applications nowadays. It offers a seamless user experience and easier authentication and authorization when compared to the traditional username and password methods. When implemented correctly and mindfully, it can be more secure than traditional authorization since users don’t have to share their credentials with the third-party application to access a certain resource. We all prefer to sign in using Google, Facebook, or LinkedIn instead of creating an account with new credentials every time we need to register to a new website. The OAuth protocol has made our lives much simpler.
Well-known OAuth service providers are very reliable. Signing in with Google or Facebook can give us a certain sense of security, and rightly so. The protocol has been tested extensively, and vulnerabilities have always been patched fairly quickly. But this sense of security can be a false one.
The security matter is a little tricky. The OAuth service providers have left the developer a lot to think about. In fact, a secure OAuth service implemented incorrectly by an unaware developer can lead to huge data thefts. Protecting the Google Drive files of a user for example starts at the third-party app level.
We will look at the most common vulnerabilities encountered in third-party applications implementing the OAuth protocol to authorize their users. Remember, the protocol itself is secure and reliable, its implementation can be vulnerable.
Stealing OAuth Token via Referer
When your application requests authorization from the OAuth server on behalf of a user, the OAuth server sends back a code to the web application, this code is sent again to the OAuth server for verification. If in the process the user gets redirected to another page, the code will be visible in the
Referer
header of the HTTP request. Thus, your code will get leaked to external websites which will compromise the logged-in user resources on the OAuth server.Note: The
Referer
header is a header in HTTP requests that communicates to the Host the URL the request is sent from.To mitigate this vulnerability, the developer needs to ensure that his web application does not contain any sort of html injection. If it does, the attacker can set up an image tag to his webserver and find a way to redirect the user to it. He can then steal the code from the
Referer
header of the request.Stealing OAuth Token via redirect_uri
As we have seen in the Introduction to the OAuth protocol, the application initiates the authorization process by a request to the OAuth server:
https://www.example.com/signin/authorize?[...]&redirect_uri=https://demo.example.com/loginsuccessful
The request always contains a
redirect_uri
parameter used by the OAuth server to send back the token to the application after the user has given its consent. In case the values of this parameter are not controlled or verified, an attacker can easily modify this parameter and redirect the request to his website where he implements a handler to receive the token and access the restricted resource.https://www.example.com/signin/authorize?[...]&redirect_uri=https://localhost.evil.com
Sometimes these URI are blocked. The attacker can redirect to an accepted Open URL like this,
https://www.example.com/oauth20_authorize.srf?[...]&redirect_uri=https://accounts.google.com/BackToAuthSubTarget?next=https://evil.com
or
https://www.example.com/oauth2/authorize?[...]&redirect_uri=https%3A%2F%2Fapps.facebook.com%2Fattacker%2F
OAuth implementations should never whitelist entire domains, only a few URLs so that “redirect_uri” can’t be pointed to an Open Redirect.
Cross-Site Request Forgery
Cross-Site request forgery can happen when an attacker succeeds in making a victim click on a link, thus generate a request that he does not intend to generate. Cross-site request forgery is usually mitigated using a CSRF token that is usually linked to the user’s session to help the application verify the identity of the person issuing the request. The ‘state’ parameter in the OAuth protocol serves as a CSRF token.
Let us see how a CSRF OAuth attack works and how the ‘
state
’ parameter can be used to help mitigate the vulnerability.Let us start by assuming that I am the attacker and you are the victim.
I visit a web application and start the process of authorizing that application to access a service provider using OAuth. The app asks the service provider for permission to request access on my behalf, which is granted. I am redirected to the service provider’s website, where I would normally enter my username/password in order to authorize access. Instead, I trap/prevent this request and save its URL. I somehow get you to visit that URL instead. If you are logged in to the service provider with your own account, then your credentials will be used to issue an authorization code. The authorization code is exchanged for an access token. Now my account on the app is authorized to access your account on the service provider.
So, how do we prevent this using the
state
parameter?The app should create a value that is somehow based on the original user’s account (a hash of the user’s session key, for example). It doesn’t matter what it is as long as it’s unique and generated using some private information about the original user. This value is given to the state parameter.
This value is passed to the service provider in the redirect. Now, I get you to visit the URL I saved.
The authorization code is issued and sent back to the client in your session along with the
state
parameterThe client generates a
state
value based on your session information and compares it to the state
value that was sent back from the authorization request to the service provider. This value does not match the state
parameter on the request, because that state
value was generated based on my session information, so it is rejected.Other vulnerabilities found in OAuth implementations include the ability to execute XSS (cross-site scripting) using the redirect_uri parameter, the OAuth Private Key disclosure (the key can sometimes be revealed when decompiling a mobile application), and the Authorization Code Rule Violation (when an authorization code can be used more than once, to issue several access tokens). These vulnerabilities are usually rarer than the ones discussed above, but this doesn’t make them less critical. A developer should be aware of all the best practices to ensure the reliability of his web application.
If you’re interested in web security, you can check the following articles:
Resources: