Installed Python App And Google Client ID - python

I'm a python beginner, and I want to make a basic google tasks client. It'll be a native app. The point I cant get is how to keep the 'client secret' actually secret, as it's to be included in the program code.
I've searched and found a post, quoting a google forums post, and basically suggesting to give the thing away.
I have spent hours trying to get the thing, but, I have no answer at the moment. So, I have two questions to ask:
What are the consequences of giving the client secret away?
If letting people see the secret is dangerous, is there a way to keep it secret, or, is there a way to do a classic login to support application specific passwords to log into the google account?

I assume you're talking about OAuth.
Yes, you embed the secret - but no, it's not really a secret; see another post here: OAuth - embedding client secret in your application?.
Google's docs actually say the same thing; from : https://developers.google.com/accounts/docs/OAuth2#installed
The client_id and client_secret obtained during registration are embedded in the source code of your application. In this context, the client_secret is obviously not treated as a secret.
And there's no point in trying to protect it - it has to make it's way over the wire to get to Google, and anyone with Fiddler, etc. could watch it in plain text.
As to impact: the idea behind the client secret, I believe, is to protect the client vendor (that's you). Theoretically, if I know your client key and secret, I could make a malicious website/client that lets users log in legitimately but then deletes all their tasks and it would look like you were responsible. That probably makes sense to defend against with web services, but for an installed client, the user presumably downloaded it from somewhere (app store, website, etc) that hopefully made sure it was legitimate.

Related

Secure deployment of client secrets in python

I'm planning to write a Kodi (former XBMC) plugin for Spotify using Python. Some time ago, Spotify deprecated their old library libspotify and introduced a new ReST based WebAPI. I would like to use this api to request data like the playlists, followed albums and other user specific stuff from Spotify. This WebAPI uses the OAUTH mechanism to authorize an application to use user-specific data.
Thus, I require a Client ID and a Client Secret. While the Client ID is public I have not problem in storing it in the sourcecode. But what about the Client Secret? This secret is required by the application to authenticate itself at spotify. Thus, it needs to be deployed as well.
How do I securly deploy this secret, such that a user of the plugin is not able to read out the secret?
I can't use obfuscation techniques because python is interpreted and a user can simply start an interpreter, import my modules and read out the reconstructed secret. The same holds for encrypting the key. The application needs to be able to decrypt the secret and because of this, I would need to deploy the encryption key as well. This is a chicken or egg problem.
Any suggestions about this? How does other software solve this problem?
EDIT: I just found this RFC6819. Seems like this is a general problem in oauth.
In this case, you can use the Implicit Grant Flow, which is designed for client-side applications where storing the secret is impractical for security reasons.

Personal Access Tokens, User Tokens

I am writing a basic python script and I am trying to use the Github API. Because I am new to the development scene, I am unsure of what I can share with other developers. Do I generate a new personal access token (that I assume can be revoked) or do I give them Client ID and Client Secret?
Can someone explain how OAuth (Client ID and Client Secret) is different from a personal access keys?
Does this logic work across all APIs (not just on Github's)?
The Short, Simple Answer
You should probably give them none of those things. They are equivalent to handing over your username and password to someone.
The Longer Answer
It depends...
Personal Access Tokens
Your personal access token is a unique token that authorises and represents you during API calls, the same way that logging via the web interface authorises you to perform actions there. So when you call an API function with a personal access token, you are performing that API action as if you yourself had logged in and performed the same action. Therefore, if you were to give someone else your token, they would have the same access to the site as they would have if you gave them you username and password combination.
Personal access tokens have attached scopes. Scopes control exactly how much access to GitHub a particular token has. For example, one token my have access to all private repositories, but another token only to public ones.
Client IDs
A client ID represents your application, rather than you. So when you create an application, GitHub gives you an ID that you use to identify your application to GitHub.
Chiefly this allows someone logging into your application using OAuth to see on the GitHub web interface that it's your particular application requesting access to their account.
Client Secrets
A client secret is a random, unguessable string that is used to provide an extra layer of authentication between your application and GitHub. If you think of the client ID as the username of your application, you can think of the client secret as the password.
Should I Share Them?
Whether you wish to share any of these things depends largely on how much you trust the other developers. If you are all working on the same application, it's likely that you will all know the client ID and client secret. But if you want to develop an open-source application that people will install on their own machines, they should generate their own client ID and secrets for their own instances of the app.
It's unlikely that you should ever share a personal access token, but if you have a bot account used by the whole team, then sharing the tokens could also be okay.

How should I store API keys in a Python app?

In my case I'm using the Dropbox API. Currently I'm storing the key and secret in a JSON file, just so that I can gitignore it and keep it out of the Github repo, but obviously that's no better than having it in the code from a security standpoint. There have been lots of questions about protecting/obfuscating Python before (usually for commercial reasons) and the answer is always "Don't, Python's not meant for that."
Thus, I'm not looking for a way of protecting the code but just a solution that will let me distribute my app without disclosing my API details.
Plain text. Any obfuscation attempt is futile if the code gets distributed.
Don't know if this is feasible in your case. But you can access the API via a proxy that you host.
The requests from the Python APP go to the proxy and the proxy makes the requests to the Dropbox API and returns the response to the Python app. This way your api key will be at the proxy that you're hosting. The access to the proxy can be controlled by any means you prefer. (For example username and password )
There are two ways depending on your scenario:
If you are developing a web application for end users, just host it in a way that your API key does not come to disclosure. So keeping it gitignored in a separate file and only upload it to your server should be fine (as long there is no breach to your server). Any obfuscation will not add any practical benefit, it will just give a false feeling of security.
If you are developing a framework/library for developers or a client application for end users, ask them to generate an API key on their own.

is twitter_anywhere_identity useable as an access token?

After messing with oauth and discovering the final leg of twitter oauth was not reliably sending back the oauth_verifier (though it seemed to authenticate anyway!), i got a bit disgruntled.
then i discovered #anywhere, the javascript twitter lib, and thought i'd give it a go.
#anywhere out of the box seems designed to allow one to do stuff like setup a tweetbox on your page. this is quite lovely but i also want my app to be able to interact with twitter server-side, i.e. from a Django script.
the auth cycle from #anywhere returns a cookie called twitter_anywhere_identity.
its format is defined as something like "userid:signature" where the signature is verifiable via hashing against the application consumer secret to prove that the cookie really came from twitter.
BUT can anyone tell me whether/how the twitter_anywhere_identity cookie (contains information that?) can be used as an access token? (if not, i'm going back to normal oauth...i guess.)
speaking of which, can anyone tell me which python library is really the best for twitter? there seem to be about 8 of them out there.
thanks!
jingles
Twitter's #themattharris pre announced #Anywhere oauth_bridge_code support. You will be able to get an oauth 1.0a token by this API.
See http://blog.abrah.am/2010/09/using-twitter-anywhere-bridge-codes.html for details.
Not yet, but in the works, if I correctly interpret an August 9th comment from Taylor Singletary:
We'll have a solution for this
announced soon that will allow you to
move more seamlessly between the
(non-OAuth 1.0a) access tokens that
make up #Anywhere requests and
server-side REST requests using OAuth
1.0a access tokens.
http://groups.google.com/group/twitter-development-talk/browse_thread/thread/2ec8f0ce984fd6e5/8e4db35fa82b22ca?lnk=gst&q=%40anywhere#8e4db35fa82b22ca
meantime, i got my OAuth1.0a solution working and i'm cool with that. ;)
JB

how can I not distribute my secret key (facebook api) while using python?

I'm writing a facebook desktop application for the first time using the PyFacebook api. Up until now, since I've been experimenting, I just passed the secret key along with the api key to the Facebook constructor like so:
import facebook
fb = facebook.Facebook("my_api_key", "my_secret_key")
and then logged in (fb.login() opens a browser) without any trouble. But now, I want to distribute the code and since it's python and opensource, I want to have some way of protecting my secret key. The wiki mentions I can use a server and ask for my secret key using the server each time my app runs (as I understand), but I have no clue as to how to start doing this, and how this should be done. I have never done web programming and don't know where I can get a server, and how to get the server to do what is needed in this case, and I don't know how can I use that server. I would really appreciate some help!
Thank you.
The relevant page on the FB developer wiki recommends a server component that just keeps your secret key and handles auth.getSession(), then gives your desktop app a session key. See that link for details.
EDIT: cmb's session keys approach is better than the proxy described below. Config files and GAE are still applicable. /EDIT
You could take a couple approaches. If your code is open-source and will be used by other developers, you could allow the secret key to be set in a configuration file. When you distribute the code, place a dummy key in the file and create some instructions on how to obtain and set the key in the config file.
Alternately, if you want to do the server approach, you'll basically be creating a proxy* that will take requests, add the secret key and then forward them on to Facebook. A good, free (unless/until your app gets a lot of users) Python-based service is Google App Engine. They also have a bunch of tutorial videos to get you started.
* E.g., when myservice.appspot.com/getUserInfo?uid=12345 is called, your service will execute something like the following.
userinfo = fb.users.getInfo(self.request.get('uid')...)
Ideally, you'd want to abstract it enough that you don't have to explicitly implement every FB API call you make.
One last thing to keep in mind is that many FB API calls do not require the secret key to be passed.

Categories

Resources