I am starting a new project (a web application) and would like it to retrieve and submit the most of its data through REST web services with AJAX. But I hardly have a good idea of how to ensure a web service to know who is accessing it and only give the data to those who are eligible.
REST web services are stateless, so the authentication should also be stateless.
The most commonly used method for this authentication is to use HTTP authentication headers (details here --> http://www.ietf.org/rfc/rfc2617.txt). Here the pre-requisite is that your should be using SSL\HTTPS otherwise these HTTP authentication headers will become vulnerable to Man in Middle Attack.
If your website doesn't use and SSL then you should probably look to other methods of authentication, this (http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/) article discusses in detail about all those methods. It basically describes mechanisms which are used by Amazon Web Services to authenticate non SSL reqeuets.
Hope this will help.
Related
Is it possible to block connections to a web service (server) from outside its domain?
For example consider a web app that fetches data from Twitter's API using Twitter's "application only auth". The web app's client uses AJAX to call it's own server, which in turn calls Twitter's API with Twitter's token.
While the token is never exposed to the client side code is there anything to stop an outside server side app from calling the web app's server using the URLs used by the client and for example exhausting the Twitter tokens rate limits?
Is it possible to block connections to a web service (server) from outside its domain?
Certainly. Set your web server's access control lists to drop connections from outside of your IP range. Alternately, install a firewall. That's very straightforward, but I suspect you mean something else by "outside its domain?"
From your description, you seem to be really asking whether you verify that you're only talking to your own client application. As a general rule, no. You can authenticate users. That's easy. If the user isn't logged in and authorized to use your service, you don't forward requests to Twitter. But you can't authenticate applications.
If you're going to accept any user who shows up, you can't stop them from using whatever client they want. There is no way to ensure that it is your unmodified client if you've allowed it to be run on their machine. They can always modify it, and they can always send you arbitrary traffic from other programs and you can't tell the difference. On the network, bytes are bytes.
It's not all hopeless; there are things you can do. See https://stackoverflow.com/a/9183066/97337 for another version of this question, and links to several other versions of the question. (They're not exactly duplicates in how they're asked, but they all wind up being basically the same answer.)
You should secure your web service with user and password security or certificate security. The basic idea is that the web service client must authenticate in order to call your web service.
Here are some technics (there are others or variations):
1) HTTP basic authentication and HTTPS
2) Mutual SSL authentication - Also called two-way authentication, is a process in which both entities authenticate with each other. The server presents a certificate to the client and the client present a certificate to the server.
3) With SOAP web services you can use WS-Security standard.
4) OAuth framework
5) With Rest services you can use options 1), 2), 4). Or implement one by your own. This are good recomendations.
As you can see, there are a lot of ways to secure a web service.
This is a similar situation to the one raised in this question:
Javascript Calling a Rest API with App Name and App Password - How Can i Secure it
Here is the architecture overview:
The site is Html5/jquerymobile
It contacts what I call a "Wrapper" service.... This is a REST API I wrote in C#, to contact another 3rd party REST API. I do this because there are credentials in the Header and the API uses Basic Authentication. Credentials are therefore not publicized as they are only known server-side.
My "Wrapper" service does not currently implement any additional security. It is currently accessible from anywhere. The easiest and quickest way to lock it down is to restrict by IP, so no other IP anywhere except the server can actually contact my wrapper service.
The questions:
Is the locking by IP the only way to ensure that the API won't get hammered if it was otherwise accessible from anywhere?
If I convert this using Phonegap (which I have... and deployed successfully on Android), obviously the native app won't work if the web service is restricted.
Is there a way around this so I can allow traffic only from the mobile app, and not from any other source? I'm thinking along the lines of MD5 hash or something that could be sent to the wrapper API.. but unfortunately I'm thinking that info can easily be "sniffed".
Is my only viable option here to release the app as a web app, forcing browser use, thereby removing any concerns about allowing my web service to be hammered??
I believe the answer to this is a combination of a user token and encrypting the message through SSL.
The server can issue a valid user a token so we can identify him in future requests.
Encrypting it via SSL will ensure that this token cannot be sniffed.
https://security.stackexchange.com/questions/12531/ssl-with-get-and-post
I'm building a restful web-service based on Spring. I'm using Spring Security. It will be accessed only by desktop applications. Basically a machine-to-machine web-service.
I want a custom service that does the authentication. Then perform other, more sensitive operations based on the result of the authentication.
Another option is to send the credentials in the body of each request and basically do the authentication each time.
Logic says that the first approach would be the most efficient because there is quite some overhead in authenticating each and every time.
What do you suggest related to this? To go stateless or stateful? Are there major disadvantages to the stateful approach?
Up to this point I read some chapters from Java Web Services Up and Running
and also several questions from SO such as this.
The REST way to do this is, as stated in the links you provide, to authenticate on each request, and NOT to keep sessions.
As for authenticating with username/password on each request, it is secure if you can use ... a secure layer (https); else, the pair is sent in clear text and discoverable.
Another option is to use something like the AWS way to do it (Links to Amazon here and here, for example). Here for other explainations : buzzmedia and samritchie
Maybe OAuth is an option, but I don't have experience with it.
To start with REST Service (Client - Server) I will strongly recomend you to use Restlet
Authentication to this REST Service can be defined using ClientResource. Example :
private static ClientResource getClientResource(String uri) {
ClientResource clientResource = new ClientResource(uri);
clientResource.setChallengeResponse(ChallengeScheme.HTTP_BASIC,
"username", "password"
);
return clientResource;
}
We currently have a SOAP based web service that our in house applications use to authenticate users. Basically, they send a SOAP request with the username and password. The web service authenticates their credentials against our data store and returns user information if the authentication is successful. The web service is secured using BASIC authentication and SSL.
We need to make modifications to this web service and I was considering re-writing it as a REST service. The REST services I have created in the past have been fairly simple and had no need for security. I have never created a REST service that used sensitive information, so I have a couple of questions / concerns:
First, is there a best practice for sending sensitive query parameters (user credentials) to a REST service securely? I can still use the BASIC authentication and SSL.
Second, if I send a query to a REST service using POST, is it still considered RESTful, or is GET required for REST queries?
You can use SSL and Basic authentication with REST web services as well.
HTTP GET is usually used for data retrieval (queries) but you can use HTTP POST as well. GET is especially useful if you can use any type of HTTP caching. POST is usefull if you need to transfer a lot of data to define your query or if your web service operation expects some complex data format instead of simple arguments.
Instead of doing the authentication via REST, you might also consider a networked authentication protocol to use in conjunction with web services. Technologies like Kerberos and OAuth were designed for these sorts of use cases.
To answer your questions, however:
REST encourages you to leverage HTTP and related protocols, so using SSL and BASIC authentication is quite appropriate.
REST encourages the use of not just GET and POST, but even other HTTP "verbs" such as PUT and DELETE. Use GET only for idempotent operations with no side-effects.
Going from SOAP to REST is taking a step backward as far as security goes.
As far as best practices:
Don't roll your own security. Use a framework or existing library that has been peer-reviewed and tested.
Don't pass unencrypted static keys. If you're using HTTP Basic and sending it across the wire, encrypt it.
Ideally, use hash-based message authentication code (HMAC) because it's the most secure.
Why REST security doesn't exist
I am making heavy use of async requests by Javascript to the webserver. Since I am building a multitenant application, I want to restrict access to the json services on the user level.
I read a lot about OAuth being recommended for consumer authentification. In my scenario, would the Javascript (client) side be regarded as the consumer and, hence, would you recommend using OAuth for that purpose? If not, what alternatives would you recommend?
OAuth is best at providing a method other than direct sharing of username and password with third party applications or web sites. I would use OAuth or something like it only in the case that you need to provide this type of third-party access to your web application.
If the JS client will be running in a web browser that the user has already logged in to your service, you might just as well use the session cookie that you have already established to authenticate each request.
In fact, such a session cookie will automatically be shared as part of any XHR to your web service.