Right now there are many good “discussions” on OAuth2 security happening. Some are constructive, some rather destructive – and some simply hack one or the other website to prove the point.
In my opinion there are a number of reason OAuth2 has a rather bad reputation right now. In this post I want to focus on the problems, in the next post what we can learn and how IdentityServer (hopefully) mitigates them.
The spec is too relaxed
When you read the spec, you’ll see a lot of “out of scope” or “at the discretion of the implementer” phrases and many “SHOULDs” and “MAYs”. Or in other words, while writing the specs there were too many interests clashing, resulting in too many ways to achieve the same thing. This lead to changing the name from “OAuth2 Protocol” to “OAuth2 Framework”. WS* anyone?
Also the lack of a token type specification lead to many homegrown token formats that were missing one or the other important security features (like audience checking, encapsulated tokens…). Writing your own token format/implementation is hard, try to avoid that!
I think we really need something like a “basic” profile that hits the 80/20 use cases with exact instructions and guidance for the implementer.
OAuth2 looks too easy
Well – what I mean here is, in WS* world we all knew shit’s hard. In the mind of many people OAuth2 is just a bunch of redirects and HTTP posts. easy. job done.
All I can say is, we are still trying to solve the same non-trivial (read: hard) problems, just using different technologies. Just because one knows HTTP does not mean he also knows how to implement security protocols.
Even the big guys like Facebook got it wrong several times – and some are still playing a dangerous game (see redirect URI based attacks later in my reference links).
Lots of attack surface
Every aspect of OAuth2 can be controlled via input parameters (like query strings or the post inputs). If I were the security tester – of course the first thing I’d try is fuzzing them and see what happens. And catastrophical things happened.
Input is still evil, even when it comes via some specified protocol. Things like response types and redirect URI should come from the authorization servers configuration database, not from external input.
Security theater is a “technique” to make you feel secure/safe while actually doing nothing (see here).
While the OAuth2 flows for native/mobile apps have all the best intentions – namely the developer does not need to deal with the user’s password (and thus not store it) etc. – it does not help you to distinguish between good and bad apps.
No one can make sure that this windows with the authorization server UI is really the authorization server, even when it looks exactly like a browser window!
So in other words, the moment you installed an application on your device, you already made a trust decision. OAuth2 cannot safe you here.
That said, IMO developers should use the implicit flow because that’s (even with a little awkward user experience) still better than dealing with credentials yourself. Windows 8 is a very good example of a modern approach to the problem. The WebAuthenticationBroker API that is built right into the operating system allows for an easy way to do OAuth2 style authorization (and OpenID connect style authentication).
OAuth2 in not an authentication protocol
OAuth2 is an authorization protocol – that’s a huge difference. Everybody who confused the two terms has learned the hard way. Don’t follow them.
OpenID Connect specifies how authentication works on top of OAuth2 – just eight more specs to read.
But – Google, Facebook and friends do authentication with OAuth2 – what do you mean? Well they all do it either using some custom extension, or like Google, OpenID Connect and call it OAuth2 sign-in.
Bearer tokens means that there is no binding between the access token and the HTTP request. In other words whoever manages to steal a token from you (e.g. on the wire) can use that token to do requests on your behalf.
All OAuth2 security currently relies solely on SSL/HTTPS to protect access token transmission. This would be OK in a perfect world. In the real world developers and/or infrastructure like to bypass SSL.
I can only speak for developers – NEVER EVER disable SSL certificate validation. NEVER EVER.
Unfortunately when you search for “how to handle SSL validation errors” on the internet, it is more likely to find information on how do disable validation (in any popular programming language) than a real answer to the question. Shame on them.
An alternative to bearer tokens would be MAC tokens. Yes they are a little harder to program against – but not much. We need this alternative – but there is currently no spec.
Here’s some further reading material. Many of the above points were inspired by the following articles. I totally recommended reading every single one:
- Eran Hammer: Bearer Tokens are a terrible Idea
- Eran Hammer: OAuth2 without Signatures is bad for the Web
- Eran Hammer: OAuth2 and the Road to Hell
- Eran Hammer: OAuth2: Looking back and moving on
- John Bradley: Problem with OAuth2 for Authentication
- Vittorio Bertocci: OAuth2 & Sign-In
- Egor Homakov: How we hacked Facebook with OAut2 and Chrome bugs
- Nir Goldshlager: How I hacked any Facebook Account…again!
- Zach Holman: OAuth will murder your Children
Oh – and last but not least – please read Tim Bray’s post on OAuth2 which I think is a really good and balanced view on the topic.
There is no point whining about turning off cert validation. Turning it off comes built into all the tutorials from Microsoft. It comes built into the ADFS product. Getting folks onto the first websso “hit” means removing the barriers. Formal certs, public SSL endpoints, hookups to DNS are pains – that most corporate programmers cannot solve – being a bureaucracy.
I teach this: first make it work without (ssl) cert hassles; use the null_with_null ciphersuite if you must, for all it matters. Then you focus on what determineing what that “beyond what SSL does” is doing in addition (be that addition: ws-trust, ws-fedp, SAML2, or OAUTH handshakes). One may learn that all the OAUTH fancy security is little more than a password-signed token blob (over SSL), with a shared password key management regime!
But at least, messages flow, protocols can be analyzed.
Yes, the likelihood of folks regressing to 0.0001% security level is high, especially if it now costs 0.001$. But, having high cert trust in a world of useless messaging trust doesn’t do anything anyay (apart from give a false sense of assurance).
I am not whining, and I am not talking about a teaching situation.
So Dominick, you are a leader in this field – what’s next? Are you going to follow suit with Eran Hammer?
I think we should fix OAuth2. Best thing I can do is working on my own implementation. The IETF should work on a “basic profile” of their spec. But that is out of my scope (pun intended).
Do you plan to add MAC tokens* to Authorization Server, which currently only supports JWT? What risks, if any, are there with JWT bearer tokens?
*such as defined in https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-http-mac/
MAC are not token types – they define how the token can be bound to a request. JWTs will/do support MAC semantics. And yes once the specs have all been stabilized we will support them. But not in AuthorizationServer but rather in IdentityServer v3.
“JWTs will/do support MAC semantics.”
Do you mean there’s a usage where a JWT would have a signature that includes the uri (and maybe params) of the call to the resource server? I know the normal usage of JWTs has the signature including the request to the authorization server, but it’d be great one could also do the same when sending the resulting access token to the resource server. With the goal being that a leaked access token couldn’t be used by any other client because they wouldn’t be able to sign the resource request with the original client’s key.
I think you misunderstand how PoP works. The JWT just holds the proof token. Everything else happens outside of it.
I certainly didn’t ask the question well. I am just trying to figure out what you meant by “JWTs will/do support MAC semantics”?
See here: http://tools.ietf.org/html/draft-jones-oauth-proof-of-possession-00
That’s how you can transmit PoP keys using a JWT.
Section 3 of the “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants” draft mentions “Holder-of-Key Assertions” that sound like an alternative to that MAC spec. Pity they chose not to define that mechanism.
two general types of assertions:
1. Bearer Assertions: Any entity in possession of a bearer assertion (the bearer)
can use it to get access to the associated resources (without demonstrating
possession of a cryptographic key). To prevent misuse, bearer assertions need
to be protected from disclosure in storage and in transport. Secure
communication channels are required between all entities to avoid leaking the
assertion to unauthorized parties.
2. Holder-of-Key Assertions: To access the associated resources, the entity
presenting the assertion must demonstrate possession of additional
cryptographic material. The token service thereby binds a key identifier to the
assertion and the client has to demonstrate to the relying party that it knows
the key corresponding to that identifier when presenting the assertion. This
mechanism provides additional security properties.
The protocol parameters and processing rules defined in this document are intended to
support a client presenting a bearer assertion to an authorization server. The use of holder-of-
key assertions are not precluded by this document, but additional protocol details would
need to be specified.