API Authentication via JavaScript SDK - javascript

I am building a JavaScript SDK for our API. The API currently requires (2-legged) OAuth authentication. Obviously this isn't suitable for a JS SDK since the key and secret are in plain site (in the JS code).
Facebook only requires your app id when you init their JS SDK, so I would like to implement something similar (or of similar simplicity). When a developer requests a key we require their app's domain. I was thinking of detecting the IP address of the submitted domain (for example myclientapp.com has 192.168.0.0 IP). And then authenticating JavaScript requests by confirming the remote hosts IP address matches.
Is this the best/easiest way of doing this?
UPDATE: As Rup pointed out the remote IP will be the client and thus not match the apps URL's IP. So that's out. So to reiterate I'm looking for a solution that will allow me to enforce some form of authentication in my JavaScript sdk for my API that can't be spoofed by someone else (trying to be someone elses app).
Thanks,
Gavin

Authenticate the user instead.
Have the (claimed, but untrustworthy) app id passed into your init(), jsonp out to your domain, then either:
Return a code valid for making API requests with, if the user is logged in* and has already authorized the app.
Pop up a window to your site (or redirect, or whatever) to have the user login (if needed) and authorize the app.
You'll have control of the user experience during authentication, and can do some human verification of the app id (show the claimed logo, name, etc.).
This does assume that you even have a notion of users, like Facebook does.
*Check cookies, not all browsers accept them in response to ajax requests; but all browsers will send them.

Related

Spa app w/ Web API security concern. Can a logged in user with a JWT make random requests to API

I have a security concern about building a SPA application.
What is stopping an end user to make calls to my Web API as long as they have a token?
For example: I am an end user to a Spa web application and I login through the login form. Get access to the JWT token provided to me (assuming this is easy). Then open up postman and try making every call possible putting that token in the header of every request.
I am assuming the only calls I would be able to make are the ones I would be authorized to make through the UI due to Web API authorization.
Is there any type of security out there to prevent this or is it basically just make sure your Web API has proper authorization?
There is absolutely no difference here to regular websites/web applications. Yes, anyone can try to make any HTTP calls they wish to your server. That holds for plain websites, jQuery sites, SPA sites, mobile applications or Flash games. Your server needs to do the proper authorisation and validation to ensure the user is allowed to do what they're attempting to do.

Oauth2 - can hacker fake google app engine requests if he knows access token

I am developing applications on Google App Engine, and am looking into the OAuth2.0 details. My question is the following: if a hacker intercepts an OAuth2.0 access token, can he fake requests from one of the "Authorized JavaScript Origins" defined in the Google Cloud Console?
A bit more details if it is unclear: in the Google Cloud console, you can define a OAuth2.0 client id which you send with your javascript using Google's JS api (complete flow here). Part of the process is that you get an access token, which you then use to authenticate subsequent requests. As an extra layer of security, all requests need to come from a specific origin that you define in your cloud console (see image). So only requests from that domain are accepted.
But I am wondering, if a hacker did know to get hold of an access token from one of my users, the request would still need to come from the authorized origin.
Can that hacker then go to https://myapp.appspot.com, tweaks the javascript with for example chrome Javascript Console, and use the access token from the user to make malicious calls as if he was the user he stole the token from?
As I see it, then the request is coming from an authorized JS origin, and with a valid OAuth2.0 access token. What am I missing?
In the case of OAuth2.0 in appengine, the user is just giving the consent to the application to use the services oh his behalf only. But the real communication is between the JavaScript app which is running on the AppEngine and the Service Provider. User is not included in making the calls it is the app which makes call to the API on behalf of the user.
Please going through the below link to grab the whole concept
https://developers.google.com/api-client-library/python/guide/aaa_oauth

How to communicate securely (with proper authentication) to a 3rd party api on the client?

Consider the usecase in which a website uses a paid analytics package to track user behavior on said site.
In that case the website needs to securely communicate with an API of the analytics provider (all clientside through javascript).
How can this be done securely? To my understanding of the various authentication protocols a secret token is always needed to setup a secret-handshake between client and server. Using oAuth1a this is all packed in HMAC, etc. but still the secret must be available.
Given that:
the secret code must be available to the client in javascript to do authenticated calls
javascript on the client can obviously be inspected by anyone
How would you keep the secret safe? It seems you can't, but how then do all these paid 3rd party services which communicate through clientside JS keep things secure?
As stipulated by the referenced answer below, it seems Google Maps API is doing this with the HOST header which apparently (?) can't be spoofed.
How does Google Maps secure their API Key? How to make something similar?.
Thus, having a sever-side map which uses a map of <apikey -> allowed HOST headers> would do the trick.

How to share authentication between website and service for Ajax

I have a WebSite (MVC 4) and WebService (Web API). WebSite has an authentication cookie and it decrypts that in order to send a secure token on to WebService when the WebSite server side code calls the service. That works fine.
However, the WebSite has JavaScript that I would like to call the WebService directly. I've tried sharing the MachineKey and Auth information, but the cookie is not carried across the WebApi.
My fallback is to route all calls to the WebService via the WebSite; but that's ugly and slow.
Any ideas?
The correct answer is Darin's. In order to share a login cookie between a services site and a web site, they will both have to be on the same domain; so e.g. the services site could be at
http://svc.mysite.com
And the web site could be at
http://www.mysite.com
Then the browser will allow the two sites to share the same cookie.
An alternative would be to have the site authenticate to the services site and get a token of some kind it could pass to the javascript. However, unless you were running on HTTPS this would be highly insecure, as the token would be available "in the clear".
A final mechanism (and the most common solution I think) would be to route all API accesses through the web site, but this is not ideal in many circumstances.

Securing my Node.js app's REST API?

I could do with some help on my REST API. I'm writing a Node.js app which is using Express, MongoDB and has Backbone.js on the client side. I've spent the last two days trying to work out all of this and not having much luck. I've already checked out:
Securing a REST API
Securing my REST API with OAuth while still allowing authentication via third party OAuth providers (using DotNetOpenAuth)
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
http://tesoriere.com/2011/10/10/node.js-getting-oauth-up-and-working-using-express.js-and-railway.js/
I want to keep my backend and frontend as separate as possible so I thought about using a carefully designed REST API would be good. My thinking is that if I ever get round to developing an iPhone app (or something else like that), it could use the API to access data.
BUT, I want this to be secure. A user has logged into my web app and I want to ensure my API is secure. I read about OAuth, OAuth 2.0, OpenID, Hmac, hashes etc... I want to avoid using external logging in (Facebook/Twitter/etc) I want the registering and logging in to be on my app/server.
...but I'm still confused here. Maybe it's late at night or my brain is just fried, but I could really do with some steps on what to do here. What are the steps for me to create a secure API?
Any help, any information, any examples, steps or anything would be great. Please help!
In order of increasing security / complexity:
Basic HTTP Auth
Many API libraries will let you build this in (Piston in Django for example) or you can let your webserver handle it. Both Nginx and Apache can use server directives to secure a site with a simple b64encoded password. It's not the most secure thing in the world but it is at least a username and password!
If you're using Nginx you can add a section to your host config like so:
auth_basic "Restricted";
auth_basic_user_file /path/to/htpasswd;
(Put it in your location / block)
Docs: http://wiki.nginx.org/HttpAuthBasicModule
You'll need to get the python script to generate that password and put the output into a file: http://trac.edgewall.org/browser/trunk/contrib/htpasswd.py?format=txt
The location of the file doesn't matter too much as long as Nginx has access to it.
HTTPS
Secure the connection from your server to the app, this is the most basic and will prevent man in the middle attacks.
You can do this with Nginx, the docs for it are very comprehensive: http://wiki.nginx.org/HttpSslModule
A self-signed certificate for this would be fine (and free!).
API Keys
These could be in any format you like but they give you the benefit of revoking access should you need to. Possibly not the perfect solution for you if you're developing both ends of the connection. They tend to be used when you have third parties using the API, eg Github.
OAuth
OAuth 2.0 is the one to go with here. While I don't know the underlying workings of the spec it's the defacto standard for most authentication now (Twitter, Facebook, Google, etc.) and there are a ton of libraries and docs to help you get those implemented. That being said, it's usually used to authenticate a user by asking a third party service for the authentication.
Given that you doing the development both ends it would probably be enough to put your API behind Basic HTTP Auth and serve it over HTTPS, especially if you don't want to waste time messing around with OAuth.
Here's a different way of thinking about it:
Let's suppose for a moment that you're not using an API. Your user logs into the app, providing some credentials, and you give a cookie or similar token of some sort to the user, which you use to identify that user has logged in. The user then requests a page containing restricted information (or creating/modifying/deleting it), so you check that this token to ensure that the user is allowed to view that information.
Now, it sounds to me that the only thing you're changing here is the way that information is delivered. Instead of delivering the information as rendered HTML, you're returning the information as JSON and rendering it on the client side. Your AJAX requests to the server will carry that same logged-in token as before, so I suggest just checking that token, and restricting the information down to 'just what the user is allowed to know' in the same way.
Your API is now as secure as your login is - if anyone was to know the token necessary for accessing the api, they would also be logged into the site and have access to all the information anyway. Best bit is, if you've already implemented login, you've not really had to do any more work.
The point of systems such as OAuth is to provide this 'logging in' method, usually from a third party application and as a developer. This would potentially be a good solution for an iPhone app or similar, but that's in the future. Nothing wrong with the API accepting more than one authentication method!
The answers so far do a great job of explaining, but don't give any actual steps. I came across this blog post that goes into great detail about how to create and manage tokens securely with Node + Passport.
http://aleksandrov.ws/2013/09/12/restful-api-with-nodejs-plus-mongodb/
Tips valid for securing any web application
If you want to secure your application, then you should definitely start by using HTTPS instead of HTTP, this ensures a creating secure channel between you & the users that will prevent sniffing the data sent back & forth to the users & will help keep the data exchanged confidential.
You can use JWTs (JSON Web Tokens) to secure RESTful APIs, this has many benefits when compared to the server-side sessions, the benefits are mainly:
1- More scalable, as your API servers will not have to maintain sessions for each user (which can be a big burden when you have many sessions)
2- JWTs are self contained & have the claims which define the user role for example & what he can access & issued at date & expiry date (after which JWT won't be valid)
3- Easier to handle across load-balancers & if you have multiple API servers as you won't have to share session data nor configure server to route the session to same server, whenever a request with a JWT hit any server it can be authenticated & authorized
4- Less pressure on your DB as well as you won't have to constantly store & retrieve session id & data for each request
5- The JWTs can't be tampered with if you use a strong key to sign the JWT, so you can trust the claims in the JWT that is sent with the request without having to check the user session & whether he is authorized or not, you can just check the JWT & then you are all set to know who & what this user can do.
Node.js specific libraries to implement JWTs:
Many libraries provide easy ways to create & validate JWTs, for example: in node.js one of the most popular is jsonwebtoken, also for validating the JWTs you can use the same library or use express-jwt or koa-jwt (if you are using express/koa)
Since REST APIs generally aims to keep the server stateless, so JWTs are more compatible with that concept as each request is sent with Authorization token that is self contained (JWT) without the server having to keep track of user session compared to sessions which make the server stateful so that it remembers the user & his role, however, sessions are also widely used & have their pros, which you can search for if you want.
One important thing to note is that you have to securely deliver the JWT to the client using HTTPS & save it in a secure place (for example in local storage).
You can learn more about JWTs from this link

Categories

Resources