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
Related
Here is my little API with two URL :
/api/location/list -> GET
/api/location/detail -> GET
I'm looking for a process to secure this service with authentication. For now, it can be accessed by only one user (me).
I think oAuth is too complex in my case and I found this resource for designing a simple API.
I understand the principle of private/public key and HMAC but I have a big concern about this :
Say my webservice is consumed by an ajax request with GET verb. I have something like /api/location/list?apikkey=userid&hash=abcde.
A end user can easily sniffed the network during the request (via a simple chrome console), capture full url and access directly to the service multiple times (I think it's a case of replay attacks).
Differents resources talk about timestamp or nonce to make a request unique but I'm a bit lost with implementation.
Any ideas ?
You can try JWToken auth specs, simpler than Oauth, but avoid authorization data as url parameter if possible and use Header's request instead.
If needed consider also ssl encryption at tcp level.
Perhaps you could try to use a token-based approach for security, as described in this blog post:
Implementing authentication with tokens for RESTful applications - https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
The idea is to authenticate to an authentication resource (that can be part of your application) to get temporary token that can be refreshed with a refresh token when expired.
With the use of HTTPS, it seems to be appropriate.
I think that it depends on the security level you expect. Signature-based authentication (the AWS approach) is great but is a bit complex to implement by hand.
Hope it helps you,
Thierry
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.
I need to centralize authentication to my rest web services and make this authentication the same for all of our webservices. So I started writing an external web service to take care about the authentication.
To keep compatibility, since the authentication was performed using a HMAC signature (signed using a private key) alongside the single request (so there is no token of any sort) I thought to make all web services to send the HMAC included inside the incoming request and the StringToSign (a representation of data used to generate the HMAC).
So the Authorization service can (knowing the private key) try to compose the same signature, if it matches then answers with 200 OK and with a JSON object saying "authorized".
All this communication happens over HTTPS, but I'm trying to figure out what could happen if someone would intercept or modify this answer, making a 403 Forbidden to become 200 OK...
Should I use some sort of way to recognize this is the original answer? If so, what could I do?
I do agree that ssl certificates released by CA's are secure, but how could I make sure my HTTPS layer has not been compromised allowing an attacker to modify authorization responses?
P.S. please provide some standard solution if any, I don't want it to be related to the technology I'm using right now, since each service may use its own stack and I don't really want it to be .NET or something else because there's a proprietary implementation for the authentication mechanism.
All this communication happens over HTTPS, but I'm trying to figure
out what could happen if someone would intercept or modify this answer
This is what the S in HTTPS is for: SSL guarantees integrity of the message. If the attacker forges the request, the client will notice it.
You can ask the experts at #security.
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 have SOAP web services in production that are relying on SOAP Headers (containing plain client credentials) for the authentication. The WS are used in heterogeneous environments with .NET/Java/PHP/Python/C++ clients both web app or desktop app.
We are considering a v2 for those WS and I am wondering what are considered as the best practices for WS SOAP authentication? (reasonably secure, yet easy to handle on a wide variety of platforms).
The easiest way to handle it across a variety of platforms is to use HTTP basic authentication and HTTPS for the transport layer. WS-Security would be good if your needs go beyond simple username/password but the support is going to vary quite a bit between platforms. HTTP authentication is supported by every decent SOAP implementation.
If you have to roll it all yourself and can't use HTTPS, I'd suggest the hash-based UsernameToken portion of WS-Security. It's pretty secure and fairly easy to implement as long as your libraries have the hashing functions.
If you're doing web services, I wouldn't rely on HTTP for authentication.
WS-Security as a whole is way too big.
The way I have tackled this in the past is to use the standard WS-* features.
Instead of using the authentication feature we set the message header integrity feature on. This requires both sides of the dialog have access to public/private key pair and detects any tampering of the username field in the header. So you can be sure whoever sent the message and set the user id has access to the private key.
This provides a reasonable level of integrity if the keys are managed properly.