Don't Use OAuth for your API
ashfurrow.com
ashfurrow.com
wat.
Instagram uses OAuth2. It's right there in their doc: http://instagram.com/developer/authentication/
Second: OAuth uses access tokens, just like OAuth2. It also imposes request digests including a timestamp parameter, which prevents replays and doesn't permit forged requests if you manage to intercept an unencrypted request.
OAuth2 is arguably less secure than OAuth, because as it's being used by Instagram, the whole kit and kaboodle is wrapped up in the bearer token, which is wholly reliant on TLS for its secrecy.
Corporate network with a custom CA installed? Your account is theirs (seriously, your employer doesn't have to ask for your Facebook password to spy on you, they just have to make sure their proxy's CA is installed on your work-issued machine, and they can crack your Facebook account open like a pinata). Cert issued from a bad CA anywhere between you and the target server? Your account is theirs. Any breach in the host's enforcing of TLS? you've just leaked full access to your account to anyone that's listening. Hell, even an XSS breach can result in a leaked bearer token.
Oh, and guess what? You can still suck an auth token out of memory and use it to forge requests. And you can still suck the OAuth2 keys out of the package or memory or whatever and use them to forge authentication requests. The exact same issue exists for OAuth2 (and Instagram's usage of it) that exists for OAuth. Implicit authentication flow is great, but the core problem of "I can crack open your app, take your client ID, and use it to create authentication requests for my app while masquerading as you" still exists. With OAuth, you also have to steal a client secret in addition to a client ID, but the end result is the same.
OAuth2 is a lot more friendly than OAuth for client developers, I'll grant that, but it's just flat wrong to argue that it has some mystical protections against the problem that aren't present in OAuth.
> If you’re building an app that does not have a server component (a purely javascript app, for instance), you’ll notice that it’s impossible to complete step three above to receive your access_token without also having to ship your client secret.
I guess I've misspoken here. Instagram uses OAuth for authentication, but actual calls to API endpoints are sugned by appending your access_token, not signing each request with OAuth.
That's... how OAuth works. Plus, later on in the same paragraph you quoted from, that alternate flow is described as being part of the OAuth spec.
Might want to understand the system before bashing it.
OAuth 2 requests are identified by a bearer token, and have no shared secret signing.
At the end of the day, all information on the client is subject to compromise. Period, paragraph, end of story. Any identification system that relies on a shared secret is subject to compromise as long as that shared secret is stored on a client-controlled device or ever entered into memory. That's true for OAuth, OAuth2, basic auth, pubkey authentication, passwords, biometrics, and literally every other single-factor identification scheme on the planet.
And: Bearer Token is as good as the session cookies that are used in every app everywhere.
There's a valid criticism of OAuth2, and that's that there are lots of decisions that are left up to the Authorization server implementer, and they need to know what they're doing. And this is security: no one knows what they're doing well enough.
I use and enjoy OAuth2, and I'm not trying to bag on it; you're absolutely right in that it's up to the server to do things Right (and few people do; the fact that nearly nobody uses the state parameter is evidence enough of that!). However, I do think it's ridiculously faulty to hold Instagram's bearer token authorization up as the "secure way" to do things in contrast to OAuth1.
I think that both OAuth and OAuth2 are plenty secure in most use cases. TLS provides Good Enough(tm) protection for the vast majority of bearer token transactions, and as you point out, there's always MAC if you don't trust the integrity of the transport. But I do think it's ignorant to claim that OAuth 1 is insecure because you can pull the secrets out of a client app, while somehow claiming that OAuth 2 is secure against such attacks.
First sentence I read was: "Instagram’s API uses the OAuth 2.0 protocol for simple, but effective authentication and authorization."
"Instagram’s API uses the OAuth 2.0 protocol for simple, but effective authentication and authorization." seems pretty clear. So's this bit:
> Client-Side (Implicit) Authentication
> If you’re building an app that does not have a server component (a purely javascript app, for instance), you’ll notice that it’s impossible to complete step three above to receive your access_token without also having to ship your client secret. You should never ship your client secret onto devices you don’t control. Then how do you get an access_token? Well the smart folks in charge of the OAuth 2.0 spec anticipated this problem and created the Implicit Authentication Flow.
> Basic HTTPS auth makes it easy to crack the protocol's encryption and get the username and password.
Does anyone know what he is referring to?
He also says:
> However, getting [a value] isn't difficult; it's easily accessible by a malicious user using an HTTPS proxy.
That, I am fairly certain, is not a serious concern because HTTPS uses a certificate chain to prevent the use of proxys. Sure, someone capable of generating bogus certificates (the NSA, for instance, and probably several other powerful governments) can insert a proxy without your knowing, but if they can do that then they can ALSO undermine the entire world financial infrastructure. Anyone capable of doing that is probably NOT going after YOUR app.
As for proxies, I'm talking about someone with physical access to a device and network, which I believe would work for extracting unencrypted HTTP headers from HTTPS requests (that's why an OAuth signature is itself encrypted by the consumer secret and user authentication token). However, I'm not a network security expert, so maybe I am mistaken.
Interesting! Do you have any references where I can read more?
> As for proxies, I'm talking about someone with physical access to a device and network
HTTPS really does protect against someone with physical access to the network, by encrypting the data streem and preventing man-in-the-middle attacks (except by attackers who can subborn a trusted root authority). It does NOT protect against someone with full access to the "device" where the client app is running -- someone with such access can, more-or-less by definition, view all values that the program sends (including credentials).
1) Dissent against OAuth; "OAuth sucks", "Don't use OAuth"
2) Focus on the fact that Instagram doesn't use OAuth
3) Link to Instagram documentation which says they do and it's awesome:
> Instagram’s API uses the OAuth 2.0 protocol for simple, but effective authentication and authorization
> Well the smart folks in charge of the OAuth 2.0 spec anticipated this problem and created the Implicit Authentication Flow
4) ???
What'd I miss?
With OAuth 2, of course, the point is mooted a bit by the decision to go with HTTPS as the secure channel, and such a scheme seems much more plausible.