How to Keep The Oauth Consumer Secret Safe, and How to React When It's Compromised

How to keep the OAuth consumer secret safe, and how to react when it's compromised?

Summary: I would just take the risk and keep the secret in the client app.

Proxy server alternative:

The only way you can reasonable mitigate the problems I list below and make the proxy-ing work, would be to go the whole nine yards - move all the business logic for dealing with the resources on the third party webservice to your proxy server, and make the client app dumb terminal with rich UI. This way, the only actions the malicious app would be able to make the proxy perform on its behalf would be only what your business logic legitimately needs.

But now you get in the realm of a whole slew of other problems having to deal with reliability and scalability.

Long deliberation on why simple proxy wouldn't work:

Some people, when confronted with a
problem, think “I know, I'll add my
own proxy server” Now they have two
problems. (with apologies to Jamie
Zawinski)

Your assumptions are largely right. Right down to the point where you start thinking about your own server, whether it keeps the secret and proxies the calls for the client app, or it attempts to determine if the app is legitimate and give it the secret. In both approaches, you still have to solve the problem of "is this request coming from a piece of code I wrote"?

Let me repeat - there is no way to distinguish on the wire that particular piece of software is running. If the data in the messages looks right, nothing can prove it's another app that's sending that message.

At the end of the day, if I am writing a malicious app, I don't care if I actually know the real secret, as long as I can make somebody that knows it do a work on my behalf. So, if you think a malicious app can impersonate your app to the third party OAuth servers, why are you certain it can't impersonate your app to your proxy?

But wait, there's more. The domain at which your proxy service is located, is your identity to both your clients and the OAuth provider (as shown to the end user by the OAuth provider). If a malicious app can make your server do bad stuff, not only is your key revoked, but your public web identity is also not trusted anymore.


I will start with the obvious - there is no way to distinguish on the wire that particular piece of software is running. If the data in the messages looks right, nothing can prove it's another app that's sending that message.

Thus, any algorithm that relies on app-side stored secret can be spoofed. OAuth's strength is that it never gives the user's credentials to the app, instead giving the app temporary credentials of it's own that the user can revoke if necessary.

Of course, the weak point here is that a sufficiently good app can get the user to trust it and not revoke the credentials, before it finished its nefarious deeds.

However, one way to mitigate this is Google's approach of using 3-legged OAuth, instead of the standard 2-legged. In the 3-legged OAuth, there's no pre-assigned secret, but on every authentication a new access token secret is issued, along with each access token. While ultimately this suffers from the same drawback, as a bad app can read the good app's token secret from its process, it does result in the user having to approve the app access every time it needs new access token.

And of course, this also means that it's a bit more inconvenient and annoying for the user.

How to keep OAuth settings a secret?

I'd create a library integrated with the Twitter Api, and store the data in a config file in application/config/ as mentioned in given link.

To please Twitter, simply parse:

$this->load->library('encrypt');

echo $this->encrypt->encode('your given secret here');

Take the output, store it inside the config file, and when you're fetching it:

$this->load->library('encrypt');

$str_secret = $this->encrypt->decode($config['secret']);
  • Encryption
    -Don't forget to set a key as described in this link.

Note that they demand you to do that for maximum security, in case someone would get control over your ftp or similiar. However if it can be decoded, it can be read. This isn't the ultimate solution, but simply a bit more reliable one.

Is it safe to store Developer's Consumer Secret in Swift code?

Generally speaking, if it's valuable enough, any secret will eventually be compromised. The trick is to make it harder to steal than the benefit that would result from stealing it.

Specifying your API key as a string constant is a pretty bad idea. A hacker with access to the binary or intermediate bitcode could extract strings from the binary and look for high entropy constants which are likely candidates to be API key values.

Be careful, it is also very easy to store your secret in your git repository and accidentally publish it for the world to see.

As an improvement, consider obfuscating the API key in your code and computing the actual key value at runtime. For example, use a simple exclusive-or mask:

MaskedApiKey = OriginalApiKey XOR Mask

OriginalApiKey = MaskedApiKey XOR Mask

Store the MaskedApiKey and Mask in your code, and combine them at runtime to restore the OriginalApiKey. Now an attacker needs to grab two constants from your code to steal the API key. You can extend this technique to make it arbitrarily obfuscated at runtime. The logical extension of this is white box encryption

A secret is even harder to steal if it is never stored in your code in the first place. So, an alternative technique is to store the API key in an external secrets service off your app. By registering your app with the secrets service, the service can attest that the app is authentic and untampered and provide your app the API key at run time. See Mobile API Security toward the end of the article for an example.

Of course, none of this matters if your API call is made in the clear and is easily observed by a Man in the Middle (MitM) attack. Always make your API calls using TLS
(HTTPS) strengthened by certificate pinning.

Take a look at this OWASP talk for a quick overview of mobile API security.

How to store consumer secret for two-legged OAuth provider?

Take a look at this previous question. I'm not an expert on the topic, but I think you're missing part of the equation. In addition to the consumer key and secret, you'll be verifying the application that's sending the request (using an x509 certificate if you're using RSA-SHA1).

Oauth Consumer key/secret vs access_token/access_secret

Not quite. The consumer key is a value that identifies the client application that is being used to access the user resources, and the access token is the value that provides the authorization to access those resources.

A combination of the consumer secret and token secret are used to sign the request which provides verification that the request is being sent by an authorized party.

You can read more about the definitions of the oauth 1.0a spec here.

Secure handling of OAuth Consumer Key and Secret in Chrome Extensions and Gmail Gadgets

Here are a couple of options.

1) Run a proxy through your own server that protects the secrets and limits the allowed methods through your own API. This will also allow you to update the API keys in moments instead of the potential days to update an extension.

2) Obfuscate the secrets in the extension/gadget code. You can make it difficult to find but with Chrome it will be easy to pick out the keys in the dev tools network tab.

3) Say screw it, leave them in the code, and make sure no actual damage can be done using the secrets.

As for Salesforce's roadmap you will likely have to ask them and they probably won't comment.

OAuth - Security against sharing Consumer Key/Secret and list of Access Tokens

There are four tokens involved in Twitter's OAuth implementation.

  1. Consumer Key
  2. Consumer Key Secret
  3. OAuth Token
  4. Oauth Token Secret

In the case of a web application, the end user never has access to tokens 1 & 2 because they're never transmitted to the client. The communication with the Twitter API is server-to-server. In this scenario, there's less risk.

In the case of a desktop application, the "Consumer" keys are usually embedded in the binary in some way. This is an acknowledged security problem with Twitter's implementation of OAuth. A determined person can decompile/crack/unobfuscate just about any binary to get your Consumer Keys.

So, to answer your question: In the case of desktop/mobile apps, it's absolutely a question of trust. In the case of web apps, it is less so.

Does Oauth 2.0 need consumer key/consumer secret

  1. OAuth 2 providers typically issue you an identifier for your client/app and some secret/password, the OAuth draft calls these client identifier and client secret. These are used to check if a call was really issued by your application. However, OAuth covers different Authorization Grant flows which are more or less secure and do not all require some kind of secret. Google calls them client ID and client secret, Facebook calls them App ID and App Secret, but they are both the same.
  2. Yes, all cryptographic steps were moved to server side in OAuth 2.


Related Topics



Leave a reply



Submit