Web services Authentication Jungle - web-services

I have been doing some research lately about best approaches to authenticating web services calls (REST SOAP or whatever). But none of the Approaches convinced me... But i still can't a make a choise...
Some talk about SSL and http basic authentication -login/password- which just seems weird for a machine (i mean having to assign a login/password to a machine, or is it not ?).
Some others say API keys (seems like these scheme is more used for tracking and not realy for securing).
Some say tokens (like session IDs) but shouldn't we stay stateless (especially if in REST style) ?
In my use case, when a remote app is calling one of our web services, i have to authenticate the calling application obviously, and the call must - if applicable - tell me which user it impersonates so i can deal with authorization later.
Any thoughts ?

So, you have User -> clientServer -> yourServer, yes?
You need to authenticate clientServer -> yourServer, to make sure not just anyone can talk to your server.
If this is an established trust relationship (i.e. you guys chat, sign documents, and do other things "out of band"), then you can simply use SSL certs, certs that you can sign.
Basically you set up your own Certificate Authority, create a root certificate, and then create a client certificate signed by that root certificate.
You then send that certificate to the clientServer, and don't let anyone connect to your service that doesn't have a certificate signed by your root certificate.
If the client ever ceases their relationship, you can revoke their cert and they can't talk to you any more.
As for identifying the User, that will need to be part of the API. The Client should authenticate them properly, and then forward any credentials to you that you require.
That can be a first class part of your web service (like a parameter), or if you use SOAP it can be passed along in a SAML attachment in the SOAP header, that you can then extract.
WS-Security has about 8000 ways of securing SOAP web services, as you may have discovered.
So, it kind of depends on what you want to do, and other requirements. But given what little you have, this should work peachy.

Related

Is it possible to restrict web service access to it's own web app?

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.

Protecting sensitive JSON data that is sent to mobile SDK (turning app into HTTPS)

I have an API endpoint which receives and sends sensitive data to a mobile SDK (that we created). The API lives in a Django Heroku app. I need to protect this information somehow, and I am a bit confused on where to start.
A friend of mine suggested provisioning HTTPS for my heroku app. After reading SSL Endpoints for Heroku, I couldn't be more confused. I read about buying a SSL certificate, yet their are so many different kinds, I don't know which one would fit my needs.
Mainly, my questions are:
What type of SSL certs do people get to protect APIs?
Would the mobile SDK require its own type of cert to interact safely with the web API?
Where can I buy/find a cert that fits my needs?
General question about HTTPS: Without HTTPS enabled, are logins able to be compromised on a heroku application with a custom domain?
Sorry if the questions are silly, I am new to SSL/HTTPS. Thanks!
The main thing that HTTPSprotects you from is man-in-the-middle attacks: that is, someone sitting between the client and the server who reads your web traffic, either copying important data or modifying what you send. In that sense, it gives some protection from compromised logins - in that no-one will be able to sniff your password from the data - but doesn't protect you from anything else, eg getting passwords from cracking, or social engineering (phishing) attacks, etc.
In terms of what to buy, the links on that documentation give you all you need to know, so it's hard to know what you mean by your first or third questions. For the second one, certificates are for the server, not the client, so unless you're serving your mobile API on a completely different domain from the rest, you don't need a separate one.

Secure centralized HMAC-based authentication service

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.

Secure authentication without SSL?

I am creating a web service for end users which will have a front-end in the form of an Adobe AIR desktop app but users will be able to access their data through the website too. User's data will be synchronized between the server and the local data store. The problem is that I cannot get an SSL certificate. Is there a way to make this more secure....
I think I can use something like two-legged oAuth or an Amazon S3 like authentication system?
What do you recommend in such a situation?
The first question is: why can you not get an SSL certificate? I can think of two reasons:
SSL certificates are too expensive
You don't want to have a certificate issued by a third party
If your problem is #1, StartSSL provides free certificates with a 1-year validity or charges $50 for unlimited certificates valid for 2 years (including wildcards). They are recognized by both Mozilla and the Microsoft trust store.
If the issue is #2, why not issue a self-signed certificate and hard-code it into your application? That does not compromise the security of the system at all (only your particular cert will be accepted by the app), but eliminates the need to "get" an SSL certificate from somewhere else.
If you really really can't use SSL, look at challenge-response systems such as Kerberos or anonymous key-material generators like Diffie-Hellman (with an asymmetric key for server identity validation). Many methods exist for secure two-party authentication over an insecure line. The key is that the ID verification step must be challenge-response instead of a "send me your secret" scheme.

Should services ask for credentials at each request?

I wonder what is the optimal authentication method for services and webservices:
user/password is sent on each request
user/password is sent once to obtain an authentication code that will be sent on each request
Is there any alternative? Which is better? Why?
Depends on the protocol.
If the service requests are in the clear (http), then you might want to consider a secure (https) logon transaction, which gains you a limited-time token to authorise future requests (a session cookie, in effect). Then at least eavesdroppers don't get credentials that work forever, just for a limited period.
Likewise even if the logon transaction isn't secure, at least if it only happens once it's slightly harder to eavesdrop. It's also slightly harder to use.
If you don't care about security, I wouldn't even use a username/password, just an API key. Amounts to the same thing, but if the user doesn't choose it then at least it won't be similar to any of their other passwords, so it doesn't affect anything else when it's stolen.
If you care about security sufficiently that everything is done over https, then it doesn't really make a lot of difference what identification mechanism you use, AFAIK. So do something simple.
Finally, you might care about the security of the authentication, but not about the secrecy of the requests themselves. So, you don't mind eavesdroppers seeing the data in flight, you just don't want them to be able to issue requests of their own (or spoof responses). In that case, you could sign the requests (and responses) using a public/private keypair or a shared secret with HMAC. That might (or might not) be easier to set up and lower bandwidth than SSL. Beware replay attacks.
By optimal are you thinking about performance ? I would suggest to send credentials and authenticate on each request unless you really find this to be a bottleneck. SSL is not enough at all, it only provides encryption and authentication of the web service. But think about client authentication (a client cert can help here) and authorisation, may be not all users of the web service is not allowed to call all methods and all methods calls needs to be logged for auditing. In this case the user identity needs to presented for each call.
I develop and maintain a SOA based core system web service developed in WCF that authenticates and authorises against .Net based clients using windows identity and uses 2-way certs authentication against Java clients and I have no performance problem.
Steve Jessop clarified things for me:
if the credentials are memorized I should provide a transient authentication cookie after they are received,
but if the credentials are digitally stored then I should only use an API key, because anyone who can access the credential storage wouldn't need to access the cookie