Server to server authentication basics - security

While I understand the various options available for server to server authentication between REST services, I could use some clarification on the security implications of each approach.
I want a service to verify that a request received does originate from a legitimate calling remote service. No interactive users involved, assume the request happens as the calling service starts up. The three approaches usually mentioned are:
Use a fake user account and authenticate the client against the existing auth system
Use a shared secret / API key and sign the request
Use a client certificate (verifying the server is not a priority) 3.
The part I am missing is that it seems that all three methods depend entirely on the calling service's host (the client in the call) not being compromised. In the first approach this would give away the fake user password, but in the two other approaches an attacker could obtain the shared secret or the client certificate and impersonate the calling server just as easily as with approach number 1... so in what respect are 2 & 3 considered more secure?

If the host is compromised, the game is already over. You cannot hope to use network security techniques to provide guarantees about the end systems, that is not what they're meant for. Consider passwords, for example. When a user types in a password, the guarantee you have is that the entity that entered the password knows the password, that's all. Designing to be secure against compromised hosts is like trying to build a password scheme that only authorizes you if you're the real person - you're expecting a guarantee that the mechanism is not built to provide.

If you want to check the calling server is not compromised you might want to use TPM based verification of the calling server in case the machines have TPMs on them. Once it has been verified that it is not compromised any of the above 3 methods would be secure.(ref: http://en.wikipedia.org/wiki/Trusted_Platform_Module)

Related

Ensuring Client / Server Authentication without credentials

I am looking into ways of securing the channel between my client apps and the server.
I have a rich desktop client (win) and mobile client connecting to a webservice, exchanging data.
Using SSL certificates, server and clients may trust each other. On the secured connection i can exchange username and password and therefore authenticate the user.
However i have certain circumstances where a user must connect to the server via any of the two methods without his credentials but only a literal, like say, a license plate number.
I really want to make sure that in this case i ONLY allow client connects from devices i am sure i know, since there is no further checks on the authentication and a license plate number would be a pretty common literal.
How can i ensure that only "devices" which are known to my server, can interact with my server?
If you want to authenticate the device, you'll need to find a way for the device to prove what it is, without disclosing its secret.
A system similar to a number plate would be quite easy to spoof, for anyone in a position to see that number. Depending on how much control you have on this device, you might not be able to hide it, even if the connection to your server is secured with SSL/TLS.
A potential way to do this would be to use a cryptographic hardware token (or smart card). Some of these tokens can be configured to hold a certificate and private key, with the ability to use the private key without being able to export that private key. The cryptographic operations (signing and decryption) happen on the token itself.
You can use these to perform client-certificate authentication to your server. In this case, you would know that the client has that token. This could work on the condition that you know the CAs were issued its certificates only for key pairs in such tokens: there will be a cost in administering the CA to handle this.
This would at least allow you to tie the authentication to a particular token. Whether you can integrate this with your overall device depends on the kind of device you have.
Please check if TLS Pre-Shared Keys (RFC 4279) can be used for your scenario.

Data encryption safe even with developer access

Suppose you have a server-client application.
Server keeps sensitive information that belongs to a Client.
Server will search some parameters in side the clients's sensitive information.
Thus server should decode the sensitive information with client control temporarily.
But server should not reveal the keys, by hacking it self.
I mean a developer should not try to change server sidde code and should not extract the client keys.
Is there really a way to do that?
Somewhat client permits server to decode sensitive information, but the keys instantly disappear and developer have no tricks to reveal this password?
The answer if exist, is valid also for an ideal secure cloud application. Developer or cloud hosting company should not access to decrypted information.
I am not optimistic, but worth to try asking.
So in a word no. This does not grant any security whatsoever, as you cannot trust the client. You even call out that the server will be controlled by the client temporarily, this is generally not a wise approach. Also, do not underestimate a bored developer, it is completely feasible to write some code and rip the keys. The key here is remembering that if someone has access to the box it is no longer your box.
In general, any client access to sensitive info on the server must require authentication of the client, so that you can verify that the client is exactly who he claims he his. The authentication typically involves sending a password, or some kind of authentication token (e.g., an encrypted shared secret) that was given to the client by the server through a secure channel.
As has been said many times, many ways, allowing client access to server data without proper and sufficient authentication means that you give up control of the server.

server-to-server REST API security

We're building a REST API that will only be accessed from a known set of servers. My question is, if there is no access directly from any browser based clients, what security mechanisms are required.
Currently Have:
Obviously over HTTPS
Have HTTP auth enabled, API consumers have a Key & password
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed for the request and validated at the endpoint?
Use OAuth (2-legged authentication)?
Doesn't matter - from browser or not.
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed
for the request and validated at the endpoint?
Use oauth (2-legged authorization)?
Use OAuth, it solves both these questions. And OAuth usage is good because:
You aren't reinventing wheel
There are already a lot of libraries and approaches depending on technology stack
You can also use JWT token to pass some security context with custom claims from service to service.
Also as reference you can look how different providers solve the problem. For example Azure Active Directory has on behalf flow for this purpose
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-on-behalf-of-flow
Use of OAuth2/OpenID Connect is not mandatory between your services, there are other protocols and alternatives and even custom. All depends in which relationships are services and either they both are in full trust environment.
You can use anything you like but main idea not to share sensitive information between services like service account credentials or user credentials.
If REST API security is main requirement - OAuth2/OpenID Connect is maybe the best choice, if you need just secure (in a sense of authentication) calls in full trust environment in a simplest way - Kerberos, if you need encrypted custom tunnel between them for data in transit encryption - other options like VPN. It does not make sense to implement somthing custom because if you have Service A and Service B, and would like to make sure call between them is authenticated, then to avoid coupling and sharing senstive information you will always need some central service C as Identity provider. So if you think from tis pov, OAuth2/OIDC is not overkill
Whether the consumers of your API are web browsers or servers you don't control doesn't change the security picture.
If you are using HTTPs and clients already have a key/password then it isn't clear what kind of attack any other mechanism would protect against.
Any compromise on the client side will expose everything anyway.
Firstly - it matters whether a user agent (such as a browser) is involved in call.
If there are only S2S calls then 1 way SSL HTTPS (for network encryption) and some kind of signature mechanism (SHA-256) should be enough for your security.
However if you return sensitive information in your api response, its always better to accept 2 way ssl HTTPS connections (in order to validate the client).
OAuth2 doesn't add any value in a server to server call (that takes place without user consent and without any user agent present).
For authentication between servers:
Authentication
Known servers:
use TLS with X.509 client certificates (TLS with mutual authentication).
issue the client certificates with a common CA (certificate authority). That way, the servers need only have the CA certificate or public key in the truststore, and new client certificates for additional clients/servers can be issued without having to update the truststores.
Open set of servers:
use API keys, issued by a central authority. The servers need to validate these keys on each request (and may cache the hashes of the keys along with the validation result for some short time).
Identity propagation
if the requests are executed in the context of a non-technical user, use JWT (or SAML) for identity propagation of the user principal and claims (authorize at security proxy/WAF/IAM, and issue JWT signed by authentication server).
otherwise the user principal refers to the technical user and can can be extracted from the client certificate (X.509 DName) or be returned with a successful authentication response (API key case).

Reliable ways to register a user's computer with a server

As part of strengthening session authentication security for a site that I am building, I am trying to compile a list of the best ways to register a user's computer as a second tier of validation - that is in addition to the standard username/password login, of course. Typical ways of registering a user's computer are by setting a cookie and or IP address validation. As prevalent as mobile computing is, IP mapping is less and less a reliable identifier. Security settings and internet security & system optimization software can make it difficult to keep a cookie in place for very long.
Are there any other methods that can be used for establishing a more reliable computer registration that doesn't require the user to add exceptions to the various cookie deleting software?
If you're looking to do device authentication, you may want to consider mutually authenticated SSL. Here, you'd deploy a client identity certificate to each endpoint you'd want to authenticate. Then, you set the server up to require client authentication, so that a client would need to present a valid identity certificate in order to form the SSL tunnel.
This, of course, is not a perfect solution. In reality, this presents much of the same weaknesses as other solutions (to various degrees) Once your client identity certificates go to your clients, they are out of your control; should a client give their certificate to anyone else, you lost the device authentication that you have based on it. SSL identity certificates are generally stored in a keystore on the client which is encrypted with a password or other credential needed to unlock them. While a client certificate could still be compromised, it's somewhat stronger that just a cookie or something like that (assuming you don't have a client that is trying to give away its credential). In addition, you'd want to come up with some validation routine that a client would need to go though in order to get a credential in the first place (how do I know that this is a client device that I want to remember/register?).
Remember, these types of approaches only do device authentication, not users. There are more in-depth schemes already developed for device authentication than what I've mentioned; for example, 802.1x is a network protocol where an endpoint needs to present a client-side certificate to the network switch to get on a LAN. This is out-of-scope for a web application scenario, like what you've described, but the idea is the same (put a cryptographic credential on the client and validate it to establish the connection).
This, like all other security matters really, is a risk decision. What are you trying to accomplish with such a countermeasure? What are the threats you're trying to prevent and what are the consequences if someone does log in on an unregistered device? Only your situation can answer those questions and let you see the real risk, if you need/should mitigate it, and, if so, how strong of a solution do you need to get the risk level down to an acceptable level?
the best ways to register a user's computer as a second tier of
validation
From my point of view this approach does not offer much in the aspect of authentication.
You are not authenticating a user and have no idea who is using the PC that you would accept as being registered.
The way you describe it, this step should be a configuration rule in the firewall to accept connections from specific IPs only.
IMO the filtering of the PCs is the responsibility of a firewall and it would be much better handled by the firewall than any application level filtering.
Just think that you would have the overhead in your application to examine each request and decide whether to accept it or not.
Better leave this preprocessing overhead to the firewall. That's why it is there.

Using cookies/sessions for mobile application authentication?

Is there any reason why I shouldn't use cookies/sessions for native mobile applications, usually used by browsers, to authenticate with my server and for subsequent API calls?
Clarification: It seems the de-facto method of authentication on mobile clients is token based systems like OAuth/XAuth. Why don't traditional browser methods suffice?
This depends on your application (your threat scenario to be more exact).
Some of the most common threats are
- eavesdropping (-> should encrypt)
- man in the middle (-> must authenticate other party)
- ...what are yours? (how secure is your cookie store,....)
A cookie at first only holds a token as proof that sometime you have successfully made an authentication. If the cookie is valid long enough or transport not encrypted, there is a good chance that someone someday will find out...
In addition you must take into account what additional security measures are in place, at first and most important SSL.
What is your authentication method (what credential does a client need to logon)? Do you have the possibility to work with authentication based on PPK infrastructure or is the communication "ad-hoc"?
EDIT
Wrt. to OpenAuth: as far as i understood the protocol its main concern is authentication delegation. A scenario where you authorize an agent to do some very specific task on behalf of another identity. This way you dont scatter your credentials all over the web. If you have OpenAuth in place, a client can use the protocol directly, too. So why bother adding another. But OpenAuth explicitly states that with a direct client scenario you again run into security issues as now the token is available on the device and must be protected accordingly (as you must do with your cookie).

Resources