We have a web-based application in which we are not requiring end users to login. The application uses Ajax to make calls to REST services hosted on the same server. Besides this application, we want to make sure that if any other applications / agents call the REST service they get denied.
What is the simplest way to secure a REST API like this? My guess is that we would include some sort of security token and make the call through HTTPS. However I'm not clear how the Ajax application would create/obtain/encrypt the token and generally what the lifecycle looks like.
I would rather do this outside of Spring Security or OAuth if possible. I have also read that sending username and password over SSL is enough for authentication. In this case, the app would have a "username" and password and it would send it with every request to the REST service. But how would it keep that information secret if the client is just HTML and javascript in the browser?
Thanks.
In general this is impossible. Someone could just do view source on your javascript, read the token, then do whatever they want.
https is not necessary here. For the token, probably the easiest is to set a cookie when they download the javascript from the server, then that cookie will also be transmitted with any AJAX requests.
This is not really secure - anyone can just see what the cookie is and use it, but it's the best you can do.
Related
We are developing an MVC application which links to a Web API. Currently, in order to do any calls to the API, the Javascript makes an AJAX call to the API sending a username and password for authentication. The API validates the username and password and sends back a security token. Then a second AJAX call is made to do the actual business logic, sending the security token with it.
We want to move away from this method since exposing the username and password in the Javascript is a security hole.
What we're looking at is a way to get the API to recognize where the call is coming from. For example, if the call is coming from our website, it's legitimate. Otherwise, the call is denied access.
Is there a way to do this? If so, are there any online walkthroughs on how to setup the API to do this? Thanks.
There are SNS application with 2 servers. Web backend server and REST API server.
The web server allows user login/logout with username/password, and show user information
The REST API server provides APIs like /topics, /comments, it should be stateless without session
The REST API will serve other web applications
There are some potential solutions, but neither is security.
Base Auth, the browser hold the username/password
Token with expiry timestamp, the problem is user could stay on the page until token expires
So, is there a way to protect the REST API when calling it from AJAX?
If I have understood your problem correctly I may suggest you use the Token solution. In order to maintain security you may generate new token on every request (& send it to client in response), which should be used to make next request, and disable token if it is once used or has expired.
Sorry, I meant to mention it as a comment, but I don't have enough reputation.
I'm currently running into a lot of issues with the CSRF token.
Our current setup is a Ruby API and an Angular front-end, both live on a different domain.
The Ruby back-end solely serves as an API for the front-end.
I've spend a lot of time researching this problem, but I can't find a proper solution.
So far the solutions I've found are:
Generate the token and insert it into the DOM (Different domains, so can't do that)
Let the API return the CSRF token on a GET request (Doesn't seem to work, and it's not a good solution since I don't want to make an extra request just to get the token)
So I'm rather stuck here and not sure how to continue.
Is the current implementation just not working? How do other people create an API with oauth without running into this issue?
Not sure if this will help but here is a sample of a simple todo api in ruby with angular as frontend, and i am using token for authentication generated after the user fills username and password.
https://github.com/sirfilip/todoapi/blob/master/app.rb (the api written in sinatra and sequel)
https://github.com/sirfilip/todoapiclient/blob/master/public/js/angular-todoapi-plugin.js (angular client api service that is used for communication with the api)
TL;DR: Secure your rails API with the doorkeeper gem.
This SO post seems to be the accepted answer when your api and client exist on the same domain.
In the post they outline the angularJS docs http://docs.angularjs.org/api/ng.$http :
Since only JavaScript that runs on your domain could read the cookie,
your server can be assured that the XHR came from JavaScript running
on your domain.
To take advantage of this (CSRF Protection), your server needs to set
a token in a JavaScript readable session cookie called XSRF-TOKEN on
first HTTP GET request. On subsequent non-GET requests the server can
verify that the cookie matches X-XSRF-TOKEN HTTP header
It seems that the security of storing and transferring the XSRF-TOKEN session cookie in this way hinges on having your api and your front-end be in the same domain. Since this is not the case, you may have to implement another form of authorization for any given client session, like OAUTH. I'd recommend taking a look at the doorkeeper gem. The gem will give you the ability to interact with your api as if you were any other client.
I would like to make application for mobile/iPhone/iPad.
In app I would like to make an HTTP request to a web service.
How can I ensure that this request comes from my app or desktop browser or mobile browser.
The user can change the "user agent" string in the HTTP request header.
So please any one tell me how can we do that?
You can't be 100% certain, you can just take certain steps to be almost certain.
Start by using SSL between the app and the server, that way no one can intercept traffic.
Then create an API token that is hardcoded in the app itself, and is supplied to the API with every request. The API then rejects any request with an invalid API token.
Using a custom user-agent can help, again rejecting any request that doesn't match the user agent.
There are countless things you can do to make it HARDER for people to make API requests, but it's almost impossible to guarantee the request is from the app itself. Just make sure that all API endpoints are properly secured with some kind of 'user' authentication and you should be alright.
I'd definitely recommend using SSL whatever you do though, as if you use things like API keys without SSL, then someone could intercept the request and obtain the API key rendering it useless.
My question is that suppose, in my web app, I use ajax to call upon methods on the server side, isn't it creating a security hole in the app? Like, say I have an option for the user to deactivate the account, which can be done by clicking a button. This is done via Ajax.
So, can't a hacker send a request to the server to deactivate the account instead of the user?
HELP!!!
My question is that suppose, in my web app, I use ajax to call upon methods on the server side, isn't it creating a security hole in the app?
From a security perspective, there is no difference between an HTTP request that involves JavaScript and one which doesn't (e.g. that uses a regular form, or is handcrafted).
… but you can't call methods from the client, you can only make requests to URIs. The server might cause a method to be called based on receiving a request to a specific URI.
So, can't a hacker send a request to the server to deactivate the account instead of the user?
They could, which is why you need (trustworthy) authentication / authorisation and CSRF protection (just like you would for a request to disable an account that didn't involve Ajax).
This is not a problem with AJAX alone, but with any arbitrary HTTP request that wants to authenticate/maintain a session. The user needs to be authenticated in some way in order to make requests, this is usually done with cookies. Using AJAX does not make the matter any worse though because it is still a HTTP request.
Authentication alone is not enough though, someone could always be listening on the wire and capture the authentication cookie, and thus get hold of the session - "become you". The only solution here is to encrypt the connection on a lower OSI layer level (using SSL/TLS). This is why you should always use SSL when it comes to authentication.
This Ruby on Rails security guide has a great explanation on how to deal with AJAX requests that could be potentially exploited. It's not specific to RoR so the concepts can apply to any platform.
One way to reduce the risk of cross site requests is to use POST for actions that modify or delete data.