

Don't Use OAuth for your API - AshFurrow
http://ashfurrow.com/dont-use-oauth-for-your-api

======
cheald
To quote Destroy All Software:

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.

~~~
AshFurrow
To quote from the page you linked to:

> 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.

~~~
cheald
OAuth (1) requests are signed with a combination of access token and shared
secret. I can't impersonate you (as a user) just by sucking the OAuth secrets
out of the app.

OAuth 2 requests are identified by a bearer token, and have no shared secret
signing.

~~~
AshFurrow
Thanks for the info - I've updated the post according to your feedback. I
think this is more an article discussing why you shouldn't use OAuth 1 when
OAuth 2 is available.

~~~
cheald
With all due respect, it needs some work, then. You've framed it in the
context of security, and there's been no compelling reason presented for as to
why OAuth 1 is an inferior solution to OAuth 2 from a security perspective.
Both use access tokens. OAuth2 has implicit flow, which serves to keep my
server-side client secret out of the hands of mobile users, and which I can
achieve in OAuth 1 by using a separate client secret for my mobile
distribution than I do for my server distribution.

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.

------
dutchbrit
In your post, you state that Instagram does not use OAuth. But then, you link
to their API page.

First sentence I read was: "Instagram’s API uses the OAuth 2.0 protocol for
simple, but effective authentication and authorization."

~~~
AshFurrow
They offer different authentication mechanisms depending on whether you're
writing a client or web app.

~~~
ceejayoz
Can you point to anywhere that documents that?

"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.

------
mcherm
In the article Ash writes:

> 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.

~~~
AshFurrow
Repeated username/combo requests over HTTPS produce patterns over multiple
requests that can make cracking the encryption easier. Additionally, there's
the issue of having to store usernames and passwords somewhere in the app
(hopefully not plaintext, and hopefully somewhere inaccessible).

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.

~~~
mcherm
> Repeated username/combo requests over HTTPS produce patterns over multiple
> requests that can make cracking the encryption easier.

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).

------
zippie
I'm either missing the reasons being backed up by Instagram's documentation or
my sarcasm meter is completely broken this morning.

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?

~~~
AshFurrow
Yeah, sorry about that. I was mistaken and have udpated the article.

~~~
amutzmercier
Updated with pictures of cats!

------
mvkel
I think the more important lesson here is: don't use light grey text on a
white background.

------
rabidsnail
The question here is: who is responsible for user behavior, the user or the
application? If the user is solely responsible then just using client tokens
is fine, because you can ban the user by invalidating her tokens. But how to
you ban an app? There's no good way to solve that problem if everything is
client side.

~~~
AshFurrow
The Stack Overflow question I link to offers an interesting point: OAuth would
work fine if tokens and secrets were passed out on a per-app, per-install
basis. That way you could ban a developer of an app, or an individual, if
their token/secret combo becomes compromised. Something like federated key
management: [http://www.scmagazine.com/federated-key-management-as-the-
ba...](http://www.scmagazine.com/federated-key-management-as-the-basis-for-
secure-cloud-computing/article/158089/)

~~~
bri3d
The problem is that to do per-install tokens, one needs a secure side channel
between the server and client over which to exchange these tokens, or a secure
side channel to some kind of key management/federation server. That's fine and
good, but it completely defeats the point of OAuth 1, which was to provide a
request signing method that _didn't_ depend on any other secure side-channels
to operate.

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.

------
amirmansour
What are some OAuth alternatives that you guys know of or have used in the
past? I only know of two-way SSL and SAML.

------
gmig
The title of this article is "Don't Use OAuth 1 for your API" instead of
"Don't Use OAuth for your API"

~~~
ceejayoz
It wasn't until it was pointed out to the author that the article was
completely incorrect.

