Mobile Apps and OAuth’s Implicit Flow

I manage an open source implementation of OAuth 2.0 (along with OpenID Connect and a bunch of extensions) called MITREid Connect. As the name suggests, it started out as a project during my tenure at MITRE, and we were looking to build an enterprise-class open source implementation of these new protocols for use at our company and beyond. It’s been a fairly successful project; people are using it all over the place and, most interestingly, customizing it to fit into a wide variety of environments. With that use comes bug reports and feature requests (and the occasional pull request), and we have seen the core project grow and develop in new and interesting ways. But one request has come through enough times that I wanted to take some time to talk about it:

How do we get a refresh token from the server using the implicit flow?

It seems like a reasonable request on the surface, but this question almost always comes about because the person asking it is doing something fundamentally wrong with their OAuth setup. How is that? First, we need to understand a few things about the implicit flow and refresh tokens.

What’s the Implicit Flow?

When OAuth 1.0 was written, one of the goals was to have a single way of doing things for every type of application. That way, it’s argued, everything is guaranteed to be compatible and interoperable with everything else. It turned out that even with that goal, people weren’t doing everything quite exactly the same way. When it came time to write OAuth 2.0, we embraced this flexibility and defined a set of different “grant types” or “flows” for different use cases. This gives us not only a core way to do things — the authorization code grant type — but also several optimizations designed for specific circumstances and use cases.

What’s a Refresh Token?

In OAuth 1.0, developers generally assumed that access tokens lived forever. They didn’t, of course — sometimes they expired, and often they got revoked. In OAuth 2.0, we ensconced the expiration mechanism to allow applications to limit the exposure caused by a leaked access token. But what’s a client to do when the access token expires before the client is done calling its API? You could always just do the OAuth dance again, and that’s fine, but an OAuth “refresh token” is a mechanism that lets a client fetch a new access token without bothering the user (or requiring the user to be present).

What’s All This Got to Do With Mobile Applications?

Here’s where things start to get quirky. You see, a lot of developers look at the implicit flow’s simplicity and think, “You know, that’s a lot easier to build so I’m just going to do that in my application instead of all this authorization code silliness.” And they’re right about that point, it’s simpler . But remember what we discussed above: that simplicity comes at a cost of assumptions about the environment in which the client is running. But we’re still using OAuth, so it must be secure, right? No, not at all. Use the implicit flow outside of that specific environment, and all of the assumptions upon which its security is built suddenly fly out the window.

Stealing the Redirect

In the OAuth protocol’s authorization code and implicit flows, the authorization server communicates the results of the authorization decision back to the client by attaching query parameters to a redirect URI and making the user’s browser fetch that URI. In a web-based application, either hosted on a remote server or running inside of a browser, the redirect URI is going to be coming from a server controlled by and directly associated with the application. In fact, the security of OAuth in these kinds of applications depends largely on this.

The Right Tool

Hopefully now you see why every time we’ve gotten the request to add refresh tokens to the implicit flow’s response in our OAuth server, we’ve told people “no.”

Justin Richer is a security architect and freelance consultant living in the Boston area. To get in touch, contact his company: https://bspk.io/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store