OAuth: When Things Go Wrong
Picture this: you sign up for a new app, and it asks if any of your friends are using it. In order to find out, the app asks for your email address...and your password. While it seems ludicrous now, this was once considered a normal user flow. But many apps still need permissions from third-party programs. And if users can’t do this safely, they’ll likely do it anyway.
Instead of requiring a password field, OAuth asks for temporary permissions to one particular part of an account, solving the problem with limited-permission access tokens.
How does OAuth work?
Every OAuth interaction involves four roles: The user, the application they want to use, the OAuth server, and the third-party service’s API. The OAuth authorization process can be broken down into two parts.
Part One: Front Channel Interactions
The user engages with an app and the app sends them to an OAuth server to request permissions. The server creates a temporary code for the application and gives it to the user to give to the app, but there’s no guarantee that the app receives the code as there’s a risk for interception. Because this interaction is done through the browser's address bar, the data becomes part of the user’s browser history, so it may be synced to the cloud and other linked browsers, making it easy to access.
Part Two: Back Channel Interactions
The app takes the authorization code to the OAuth server, and is given an access token in return. The app can now use the access token to make an API request. The second part of the transaction happens over back channels, where the connection is secure and the response is nearly instantaneous.
While back-channel interactions are more secure, front channel interactions guarantee that a user gives permission. The party receiving data doesn’t need a publicly accessible IP address, so it is also mobile-friendly.
What can go wrong in OAuth?
Stolen API keys. Stolen access tokens. Redirects. Phishing attacks.
Security vulnerabilities don’t go away, but as OAuth is iterated upon, it is becoming more secure.
In 2013, Twitter’s OAuth API keys for their mobile apps were leaked by extracting them from their mobile apps. This demonstrated that it's impossible to use provisioned client secrets with OAuth in mobile apps. OAuth 2.0 takes a new approach, where instead of a client secret, OAuth 2.0 uses PKCE (proof key for code exchange) to eliminate the need for the secret. In this flow, the app generates a secret, hashes it, and sends the hashed value through the URL. The user goes to the OAuth server, and gives it the hash. It gets back an authorization code, which it then takes to the app which the app can use to get an access token. But when the app exchanges the authorization code for an access token, it includes the plain text version of the previously-hashed secret. The server hashes it and compares it to ensure it matches. All this is done securely over the backend.
The issue of user consent screens
In many instances, OAuth consent screens don’t provide enough context to let the user know that something might be wrong. The challenge is designing one in a way that users can understand.
There are a few criteria that should be met to achieve this:
- The OAuth prompt has to be concise enough not to overwhelm the user with information, while still providing everything they need to make an informed decision.
- It should be clear where the user is. What service are permissions being granted for?
- What is the application seeking permissions? Identity them both by name and URL.
- Which user is logged in?
- Which permissions are being granted? Even better is to allow the user to uncheck permissions the app has requested.
Implementing these solutions can give your users peace of mind, secure their data, and make it easier to grant OAuth solutions.
To learn more about implementing OAuth 2.0 and API Access Management, read our Securing Digital Business with API Access Management whitepaper.