Foursquare API: Userless Access (client_secret key) - foursquare

Reading on some of the answers on here, people suggest doing userless access by calling Foursquare by:
https://api.foursquare.com/v2/venues/search?ll=40.7,-74&client_id=XXXXXXXXXXXXXXXX&client_secret=YYYYYYYYYYYYYYYYY&v=20111109
This means I have to include my client_secret key? Is this safe?
Clarification, I'm working on an iOS app using Foursquare search without the user logging in.

You should probably route the search requests via your server, which can add the client_id/client_secret information before passing it to foursquare. This will also be useful if you ever need to change your id/secret information, want to add caching, etc.
(That being said, it's perfectly common to put your client id / secret into your iOS app, but I would avoid explicitly publishing it anywhere, e.g. in any public source code)

Yes, it means that you need to include the client_id and client_secret.
Define safe :)
For facebook server-side application access, you include the app id and app secret as well (id|secret constructs the access token)
I think that the main idea behind this kind of access is to allow server-side access from the application and if the api access is done via a server script/code/web-service (and not via client-side javascript), this information remains a secret.
I guess it would be true to say that leaving this information somehow in the javascript code is not the best idea (= not safe!).

Related

ReST API: Should I associate the access token with a user in my database

I am building a secure ReST API on a nodeJS server so that my Android application can access the data on my site. Based on reading some other posts, I've come to understand that I should use an access token. So my idea is to do the following:
1) When the user logs in on the Android app, the app sends a request to /api/login on my site, providing the username and password (this of course needs to happen over SSL to guard against eavesdropping).
2) My server validates that the username + password match, and, if so, responds with an access token.
3) The app uses this access token to make all subsequent requests to my API.
My question is should I store the access token in the database on my server? Specifically, should I store the fact that the access token is associated with that particular user? Most tutorials I looked at did not do this, but if I don't, then what is to stop a user with this access token modifying or viewing the data of another user? Don't I need to pair an access token with a user in my database?
try using this library, i did the same type of project and this life saver was my solution.
If you need to build a secure API the things are little more complicated. You need to sign the access token with a private keystore.
Would it be a option to use a authentication service like Auth0? They are generating a JWT token for you and you only need to validate this token. The API is completely stateless. You can find a lib for almost any programming language on their website.
What you want to do is exactly HTTP Sessions do.
So, I think you can just use HTTP Session functionality It's already implemented in WAS frameworks like Django, Spring etc. If NodeJS provide session functionality, Just use session functionality in the framework. If not, look up the HTTP Session library. Maybe you can find many library that treat session implementation.

How can I generate a limited access API token for SurveyMonkey?

I'm creating a client-side application (i.e. HTML/CSS/JS in a web browser) that retrieves survey information from a SurveyMonkey account and generates an appropriate form to submit it. The application itself works fine, but it relies on knowing the API key to call get_survey_list and get_survey_details. The problem is that anyone could easily extract the key (e.g. by inspecting the network requests using the browser's debug tools) and perform more privileged operations like get_responses which is private information and thus should not be publicly accessible in this way.
Is there a way to create a "limited access API token" of some kind? For example, I would like to create one that is only authorized to perform certain types of API calls.
This is not possible, the only authorization token you can generate is a full access one as documented here.
Your best bet in this case is to have a proxy web app you can call, which then makes the API calls on the client's behalf.

client secret in OAuth 2.0

To use google drive api, I have to play with the authentication using OAuth2.0. And I got a few question about this.
Client id and client secret are used to identify what my app is. But they must be hardcoded if it is a client application. So, everyone can decompile my app and extract them from source code. Does it mean that a bad app can pretend to be a good app by using the good app's client id and secret? So user would be showing a screen that asking for granting permission to a good app even though it is actually asked by a bad app? If yes, what should I do? Or actually I should not worry about this?
In mobile application, we can embedded a webview to our app. And it is easy to extract the password field in the webview because the app that asking for permission is actually a "browser". So, OAuth in mobile application does not have the benefit that client application has not access to the user credential of service provider?
I had the same question as the question 1 here, and did some research myself recently, and my conclusion is that it is ok to not keep "client secret" a secret.
The type of clients that do not keep confidentiality of client secret is called "public client" in the OAuth2 spec.
The possibility of someone malicious being able to get authorization code, and then access token, is prevented by the following facts.
1. Client need to get authorization code directly from the user, not from the service
Even if user indicates the service that he/she trusts the client, the client cannot get authorization code from the service just by showing client id and client secret.
Instead, the client has to get the authorization code directly from the user. (This is usually done by URL redirection, which I will talk about later.)
So, for the malicious client, it is not enough to know client id/secret trusted by the user. It has to somehow involve or spoof user to give it the authorization code,
which should be harder than just knowing client id/secret.
2. Redirect URL is registered with client id/secret
Let’s assume that the malicious client somehow managed to involve the user and make her/him click "Authorize this app" button on the service page.
This will trigger the URL redirect response from the service to user’s browser with the authorization code with it.
Then the authorization code will be sent from user’s browser to the redirect URL, and the client is supposed to be listening at the redirect URL to receive the authorization code.
(The redirect URL can be localhost too, and I figured that this is a typical way that a “public client” receives authorization code.)
Since this redirect URL is registered at the service with the client id/secret, the malicious client does not have a way to control where the authorization code is given to.
This means the malicious client with your client id/secret has another obstacle to obtain the user’s authorization code.
I started writing a comment to your question but then found out there is too much to say so here are my views on the subject in the answer.
Yes there is a real possibility for this and there were some exploits based on this. Suggestion is not to keep the app secret in your app, there is even part in the spec that distributed apps should not use this token. Now you might ask, but XYZ requires it in order to work. In that case they are not implementing the spec properly and you should A not use that service (not likely) or B try to secure token using some obfuscating methods to make it harder to find or use your server as a proxy.
For example there were some bugs in Facebook library for Android where it was leaking tokens to Logs, you can find out more about it here
http://attack-secure.com/all-your-facebook-access-tokens-are-belong-to-us
and here https://www.youtube.com/watch?v=twyL7Uxe6sk.
All in all be extra cautious of your usage of third party libraries (common sense actually but if token hijacking is your big concern add another extra to cautious).
I have been ranting about the point 2 for quite some time. I have even done some workarounds in my apps in order to modify the consent pages (for example changing zoom and design to fit the app) but there was nothing stopping me from reading values from fields inside the web view with username and password. Therefore I totally agree with your second point and find it a big "bug" in OAuth spec. Point being "App doesn't get access to users credentials" in the spec is just a dream and gives users false sense of security… Also I guess people are usually suspicions when app asks them for their Facebook, Twitter, Dropbox or other credentials. I doubt many ordinary people read OAuth spec and say "Now I am safe" but instead use common sense and generally not use apps they don't trust.
Answering to 2nd question: Google APIs for security reason mandate that authentication/sign-in cannot be done within App itself (like webviews are not allowed) and needs to be done outside app using Browser for better security which is further explained below:
https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html

How do I secure REST API calls?

I'm developing the restful web app that using some popular web framework on the backend, say (rails, sinatra, flask, express.js). Ideally, I want to develop client side with Backbone.js. How do I let only my javascript client side interact with those API calls? I don't want those API calls to be public and be called by curl or simply by entering the link on browser.
As a first principle, if your API is consumed by your JS client, you have to assume, that it is public: A simple JS debugger puts an attacker into a position, where he can send a byte-for-byte identical request from a tool of his choice.
That said, if I read your question correctly, this is not, what you want to avoid: What you really don't want to happen is, that your API is consumed (on a regular basis) without your JS client being involved. Here are some ideas on how to if not enforce, then at least encourage using your client:
I am sure, your API has some sort of authentication field (e.g. Hash computed on the client). If not, take a look at This SO question. Make sure you use a salt (or even API key) that is given to your JS client on a session basis (a.o.t. hardcoded). This way, an unauthorized consumer of your API is forced into much more work.
On loading the JS client, remember some HTTP headers (user agent comes to mind) and the IP address and ask for reauthentication if they change, employing blacklists for the usual suspects. This forces an attacker to do his homework more thoroughly again.
On the server side, remember the last few API calls, and before allowing another one, check if business logic allows for the new one right now: This denies an attacker the ability to concentrate many of his sessions into one session with your server: In combination with the other measures, this will make an abuser easy detectable.
I might not have said that with the necessary clarity: I consider it impossible to make it completely impossible for an abuser to consume your service, but you can make it so hard, it might not be worth the hassle.
You should implement some sort of authentication system. One good way to handle this is to define some expected header variables. For example, you can have an auth/login API call that returns a session token. Subsequent calls to your API will expect a session token to be set in an HTTP header variable with a specific name like 'your-api-token'.
Alternatively many systems create access tokens or keys that are expected (like youtube, facebook or twitter) using some sort of api account system. In those cases, your client would have to store these in some manner in the client.
Then it's simply a matter of adding a check for the session into your REST framework and throwing an exception. If at all possible the status code (to be restful) would be a 401 error.
There's an open standard now called "JSON Web Token",
see https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for
creating tokens that assert some number of claims. For example, a
server could generate a token that has the claim "logged in as admin"
and provide that to a client. The client could then use that token to
prove that they are logged in as admin. The tokens are signed by the
server's key, so the server is able to verify that the token is
legitimate. The tokens are designed to be compact, URL-safe and usable
especially in web browser single sign-on (SSO) context. JWT claims can
be typically used to pass identity of authenticated users between an
identity provider and a service provider, or any other type of claims
as required by business processes.[1][2] The tokens can also be
authenticated and encrypted.[3][4]
Set a SESSION var on the server when the client first loads your index.html (or backbone.js etc.)
Check this var on the server-side on every API call.
P.S. this is not a "security" solution!!! This is just to ease the load on your server so people don't abuse it or "hotlink" your API from other websites and apps.
Excuse me #MarkAmery and Eugene, but that is incorrect.
Your js+html (client) app running in the browser CAN be set up to exclude unauthorized direct calls to the API as follows:
First step: Set up the API to require authentication. The client must first authenticate itself via the server (or some other security server) for example asking the human user to provide the correct password.
Before authentication the calls to the API are not accepted.
During authentication a "token" is returned.
After authentication only API calls with the authentication "token" will be accepted.
Of course at this stage only authorized users who have the password can access the API, although if they are programmers debugging the app, they can access it directly for testing purposes.
Second step: Now set up an extra security API, that is to be called within a short limit of time after the client js+html app was initially requested from the server. This "callback" will tell the server that the client was downloaded successfully. Restrict your REST API calls to work only if the client was requested recently and successfully.
Now in order to use your API they must first download the client and actually run it in a browser. Only after successfully receiving the callback, and then user entry within a short frame of time, will the API accept calls.
So you do not have to worry that this may be an unauthorized user without credentials.
(The title of the question, 'How do I secure REST API calls', and from most of what you say, that is your major concern, and not the literal question of HOW your API is called, but rather BY WHOM, correct?)
Here's what I do:
Secure the API with an HTTP Header with calls such as X-APITOKEN:
Use session variables in PHP. Have a login system in place and save the user token in session variables.
Call JS code with Ajax to PHP and use the session variable with curl to call the API. That way, if the session variable is not set, it won't call and the PHP code contains the Access Token to the API.

How to keep the client credentials confidential, while using OAuth2's Resource Owner Password Credentials grant type

We are building a rest service and we want to use OAauth 2 for authorization. The current draft (v2-16 from May 19th) describes four grant types. They are mechanisms or flows for obtaining authorization (an access token).
Authorization Code
Implicit Grant
Resource Owner Credentials
Client Credentials
It seems we need to support all four of them, since they serve different purposes. The first two (and possibly the last one) can be used from third-party apps that need access to the API. The authorization code is the standard way to authorize a web application that is lucky enough to reside on a secure server, while the implicit grant flow would be the choice for a client application that can’t quite keep its credentials confidential (e.g. mobile/desktop application, JavaScript client, etc.).
We want to use the third mechanism ourselves to provide a better user experience on mobile devices – instead of taking the user to a login dialog in a web browser and so on, the user will simply enter his or her username and password directly in the application and login.
We also want to use the Client Credentials grant type to obtain an access token that can be used to view public data, not associated with any user. In this case this is not so much authorization, but rather something similar to an API key that we use to give access only to applications that have registered with us, giving us an option to revoke access if needed.
So my questions are:
Do you think I have understood the purpose of the different grant types correctly?
How can you keep your client credentials confidential? In both the third and fourth case, we need to have the client id and client secret somewhere on the client, which doesn't sound like a good idea.
Even if you use the implicit grant type and you don’t expose your client secret, what stops another application from impersonating your app using the same authorization mechanism and your client id?
To summarize, we want to be able to use the client credentials and resource owner credentials flow from a client application. Both of these flows require you to store the client secret somehow, but the client is a mobile or JavaScript application, so these could easily be stolen.
I'm facing similar issues, and am also relatively new to OAuth. I've implemented "Resource Owner Password Credentials" in our API for our official mobile app to use -- the web flows just seem like they'd be so horrible to use on a mobile platform, and once the user installs an app and trusts that it's our official app, they should feel comfortable typing username/password directly into the app.
The problem is, as you point out, there is no way for my API server to securely verify the client_id of the app. If I include a client_secret in the app code/package, then it's exposed to anyone who installs the app, so requiring a client_secret wouldn't make the process any more secure. So basically, any other app can impersonate my app by copying the client_id.
Just to direct answers at each of your points:
I keep re-reading different drafts of the spec to see if anything's changed, and am focused mostly on the Resource Owner Password Credentials section, but I think you're correct on these. Client Credentials(4) I think could also be used by an in-house or third-party service that might need access to more than just "public" information, like maybe you have analytics or something that need to get information across all users.
I don't think you can keep anything confidential on the client.
Nothing stops someone else from using your client id. This is my issue too. Once your code leaves the server and is either installed as an app or is running as Javascript in a browser, you can't assume anything is secret.
For our website, we had a similar issue to what you describe with the Client Credentials flow. What I ended up doing is moving the authentication to the server side. The user can authenticate using our web app, but the OAuth token to our API is stored on the server side, and associated with the user's web session. All API requests that the Javascript code makes are actually AJAX calls to the web server. So the browser isn't directly authenticated with the API, but instead has an authenticated web session.
It seems like your use-case for Client Credentials is different, in that you're talking about third-party apps, and are only serving public data through this method. I think your concerns are valid (anyone can steal and use anyone else's API key), but if you only require a free registration to get an API key, I don't see why anyone would really want to steal one.
You could monitor/analyze the usage of each API key to try to detect abuse, at which point you could invalidate one API key and give the legitimate user a new one. This might be the best option, but it's in no way secure.
You could also use a Refresh Token-like scheme for this if you wanted to lock it up a bit tighter, although I don't know how much you would really gain. If you expired the Javascript-exposed api tokens once a day and required the third-party to do some sort of server-side refresh using a (secret) refresh token, then stolen api tokens would never be good for more than a day. Might encourage potential token thieves to just register instead. But sort of a pain for everyone else, so not sure if this is worth it.

Resources