How to secure a web service call over HTTP - web-services

What would be a best practice to secure a web service call over HTTP communication channel?
I aim to using extra parameters in query string to make time-limited hash values (generated by a calculation on client side) to define that sending request is valid. This will be understand by server side application how knows the client algorithm. But this way has a risk also when the client application is de-compiled!
So what is the best way? I'm looking for a dynamic algorithm, any thought?

From your comment it sounds like your need is to guard against "replay attacks" (someone sending the same request twice, when you only want for them to be able send it once). A common way to handle this is to use a nonce. At a basic level, it works like this:
1) Client wants to make a request; before doing that, it asks the server for a nonce, which is a value which will not be reused and shouldn't be predictable (e.g. based on the time).
2) Client gets the nonce from the server, then makes its request, sending back to the server the nonce it just got from it
3) If the client (or another client) then tries to make the request already made in step 2 above, the server won't accept it, because it'll contain a nonce which the server has already marked as "used."
That's a slight oversimplification, but that's how nonces work to prevent replay attacks.
Note: "nonce" comes from "number used once." But nonces don't actually need to be numbers.

Related

Does HATEOAS increase the number of calls to server?

I have never used HATEOAS with RESTAPI's and what I understand is with HATEOAS, one doesn't need to store URI's and server send's the URI's in the response which can be used to fetch other resources or related resources.
But with HATEOAS, aren't we increasing the number of calls?
If I want to fetch customer-order information and if I first fetch customer information and get URI for it's orders dynamically, isn't it an extra call?
Loose coupling can be understood but I do not understand the exact use of this Maturity level of REST.
Why should HATEOAS increase the number of required requests? Without the service returning URIs the client can use to perform a state trransition (gather further information, invoke some tasks, ...) the client has to have some knowledge on how to build a URI itself (hence it is tightly coupled to the service) though the client still needs to invoke the endpoint on the server side. So HATEOAS just moves the knowledge on how to generate the URI from client to server.
Usually a further request sent to the server isn't really an issue as each call should be stateless anyway. If you have a load-balanced server structure, the additional request does not really have a noticable prerformance impact on the server.
If you do care about the number of requests issued by a client to the server (for whatever reason) you might have a look at i.e. HAL JSON where you can embed the content of sub-resources, though in the case of customer orders this might also have a significant performance impact as if users may have plenty of issued orders stored the response might be quite huge and the client has to administer all of the data even though it might not use it. Usually instead of embedding lots of list items within a response the service will point the client to a URI where the client can learn how to retrieve these information if needed. Often this kind of URIs provide a pageable view on the data (like orders placed by a customer).
While a pageable request for sure increase the number or requests handled by the service, overall performance will increase though as the service does not have to return the whole order-data to the client and therefore reduce the load on the backing DB as well as shrinking the actual response content length.
To sum my post up, HATEOAS is intended to move the logic of creating URIs to invoke from clients to servers and therefore decouple clients from services further. The number of actual requests clients have to issue isn't tide to HATEOAS but to the overall API design and the requirements of the client.

Is a TCP socket secure or should I always check the user

I have a C++ app that connects to a nodeJS server through a TCP socket.
On socket 'handshake' the client authenticates itself with a UUID known by the server, the server then associates the account to this recognised UUID
Once a TCP socket is open, the app sends requests and the server answers through the same socket.
Is it necessary to add passphrase to every request to be sure the request comes from the client? Or is a socket supposed to be in place and remain in place?
So should I be sure the client is the client:
Only when opening the socket?
Every time a request is made?
The UUID known to the server is normally called a token. And it can be used for your scenario. However it should never be done unencrypted.
What you need to make sure is the following:
An external party (not one of the 2 members of the communication) should not be able to read the token.
The client should not connect to anything but YOUR server.
This is typically accomplished using TLS. (This is what makes HTTPS secure.)
I suggest you do some research into token-based authentication/authorization and TLS/SSL.
One last advice: do not implement the encryption code yourself but use a well used library that has as a result had a lot of testing and has good maintenance.
No, it's not "secure". Your scheme is susceptible to, just off the top of my head, replay attacks, man-in-the-middle attacks, eavesdropping, subsequent impersonation ...
A socket isn't like an actual physical pipe or tunnel. A socket is just an agreement that data marked with a certain source and destination port pair (these are just numbers) are to be treated as belonging to a particular logical data channel. This is determined by handshake and trust. There is no verification.
What you're specifically asking is whether man-in-the-middle attacks exist. Yes, yes they do.
Will requiring a passphrase be given in each packet fix that problem? No, it won't. It will be trivial to intercept and then replay. You're just giving the man in the middle the passphrase.
This is why people use encryption and other clever security schemes. If you're concerned about message authenticity and integrity, you'll need a basic grounding in communications security principles; providing one is out of the scope of this answer.

Algorithm for client validation?

Here is what I am trying to do.
I have a game and a server executable. The clients connect to the server to play.
The concern I currently have is that someone might use telnet or something to simulate a client.
Currently, the user only sends a simply hello string after they are connected and if it is correct I accept data from them.
I have tried to use certificates / ssl without success so I am trying to figure out an effective way to know if a game client is really a client.
Simply put, what would be an effective way to validate the client?
I am not concerned with a man in the middle attack since the users do not login nor provide passwords, just a session name.
I have thought of the possibility of the server sending a fixed length random string, then the client modifies this string with an algorithm, then sends it back.
I am wondering if there are better more clever ways than that.
I do actually have a certificate for my server, it is a pfx, if that helps.
Thanks
Its intrinsically difficult as a problem. Certainly there is no software you can write, that could run on a foriegn machine, that can proves its the program you wrote in an un-tampered form.
Still, there is some simple challenge response stuff you ca do to improve things.
Lets assume your client and your server share a secret (your writing it, so they can, though being software it wont be very secret.) Lets also assume you have ahandy crypt or hashing library (for things like a SHA-1 hash) Then:
Server send challenge, including a nonce (eg the time + random number).
Client sends a response, which includes a secure hash of (nonce + secret)
Server know the nonce and the secret, so they can check the hash received is correct, and thus can confirm the "client" also knows the secret.
This is a basic symmetric validation scheme.

Client to Server Authentication in C++ using sockets

I'm implementing a login/authentication system for my little server-client program. I'm wondering how to go about this, and I was hoping to get some great tips/advice from Stack Overflow as always. This is how I imagine I'll do it.
Client connects to the server.
Server sends a 'token' to the Client (based on time probably and whatever)
Client returns the username and a sha1 encrypted password, along with the token.
Server receives them and authenticates the user to the credentials in the server-side database.
The token is now verified and the user is signed in with the token.
Is this at all a secure way of doing it? I figured the client also sends a serial key or some such to form a serial / token pair, so that another client cannot fake the same token (though the token is generated by the server-side).
Implementation details aren't required, as I am capable of doing the implementation.
My question would, rather, two questions:
What ways are there to achieve a login/authentication system with sockets
What ways are there to secure my client-to-server connection
EDIT: I forgot to ask, as this is a C++ question, are there any libraries that can assist in encryption/authentication?
Security is an issue for me, so I want to be sure I do it right.
Maybe some background information. It's a game server, a person logs in with his account and is taken to a 'Lobby', where he can pick a 'World Server' to play on. The world server is a separate process running (possibly) on a different machine in the same network.
For that reason, I want to have a concept of a session in this, the user logs in and a session is generated, the login server relays the session to the world server the user picks, so that world server knows that the user is actually logged in.
I reckon the client will have to confirm the session to the world server and all that, but I'll worry about that later.
Sincerely,
Jesse
You generally do not want to send the password over the link at all, not even with encryption. The usual method is a challenge-response protocol.
The client connects to the server, sending in the user-name (but not password)
The server responds by sending out unique random number
The client encrypts that random number using the hash of their password as the key
The client sends the encrypted random number to the server
The server encrypts the random number with the correct hash of the user's password
The server compares the two encrypted random numbers
This has a couple of advantages. First, it means the password never goes over the link in any form. Second, it's immune to a replay attack -- if an attacker records the conversation, they can't replay the client's replies later to log in, because the random number will have changed.
Securing the connection (i.e., encrypting the content) is a little simpler. Typically, one of the two (doesn't really matter much which) picks a random number, encrypts it with the other's public key, and sends it to the other. The other decrypts it, and they encrypt the rest of the session using that as a key for symmetric encryption.
Libraries: Beecrypt and OpenSSL are a couple of obvious ones. Unless you have a fairly specific reason to do otherwise, TLS is what you probably want to use (it does quite a bit more than what I've outlined above, including two-way authentication, so not only does the server know who the client is, but the client also knows who the server is, so it's reasonably verified that it's not connected to somebody else who might just collect his credit card number and run with it).
Edit:
To authenticate each packet without the overhead of encrypting everything, you could do something like this:
The server sends its public key with the challenge
The client generates a random number, encrypts it with the server's public key, and sends it back with its response
The number is the first number used for counter-mode encryption
The client includes one counter-mode result with each packet it sends
Counter mode means you just generate consecutive numbers, and encrypt each in turn, using the right key. In this case, the key would be the hash of the client's password. What this means is that each packet will contain a unique random number that both the client and the server can generate, but nobody else can. By using the counter-mode encryption, each packet will have a unique random number. By starting from a random number, each session will have a unique sequence of random numbers.
To minimize overhead, you could send just a part of the result with each packet -- e.g., if you use AES in counter mode, it'll generate 16 bytes of result for each number you encrypt. Include only (say) two bytes of that with each packet, so you only have to encrypt a number once every 8 packets. In theory, this cuts security -- an attacker could just try all 65536 possible values for a packet, but if you assume the connection has been compromised after (say) two bad attempts, the chances of an attacker getting the right value become pretty small (and, of course, you can pretty much pick the chances you're willing to live with by controlling the number of bad attempts you allow and the size of authentication you include in each packet).
If security is a big issue for you, don't roll your own. You want a secure socket library. Something like OpenSSL.

Client / Server Cryptography for passwords

I am building a client/server application in C++ and need each client to provide a password. Obviously I want this to be secure during transport so I have been looking into a way of encrypting the password; so that only the server application can decrypt it again.
The problem I am having is not necessarily getting the functions to work, but rather understanding what it is I need to do in order to relate that into code. I am trying to understand and have read MSDN (feels like it) but still I am only learning so really need some clear and accurate guidance on my implementation.
Does this sound right?
I aquire a context to the CSP on both server and client.
I generate a key on the server, or load one (whatever).
and then I
export a public key from the server and send it to the client, the client imports the key and then encrypts the password and returns it so that only the server can decrypt it again.
(Fails when I try).
OR, do I then
export a session key, or an exchange key pair ( single public) which is encrypted with the exchange key pair?
Oh I am so lost, I cannot even explain clearly.
Please help me to understand this...
It really depends on what sort of authentication solution you want to be based one. The options are varied.
You could, for example, rely on the underlying OS authentication. You wouldn't need to manage passwords at all. But this requires a somewhat tighter integration with the domain in which your application is running.
Another option is to use HTTPS and simple authentication. It basically uses SSL to encrypt communication and then sends a username/password pair. Pretty simple, and supported by all web servers. You could probably find C++ code quite easily that takes care of this for you (search StackOverflow for such a question) if you don't want to rely on an existing web server like IIS being installed.
If you do not need the encrypted Communication for other things like data transfer, you can use Challenge-Response for password verification. The Password does not need to be transferred over the network and there is no risk of a replay attack in wich a third party just resends some packets. On the downside, a man in the middle (MITM) attack is possible.
If you need protection from MITM or need an encrypted channel for other communication, you should use TLS with certificates or Public-Key-Encryption with two keypairs.
Do not do anything.
This is very important. Do not implement this yourself.
Repeat do not do anything you will get it wrong.
You should use what is already available. Simply open a connection to an SSL socket and the content of the stream will be automatically encrypted and de-crypted at the other end.
Your application should simply take a username/password tupple and validate if they are correct. Do not attempt to implement the cryptographic part.