Best practice with request authentication with time-stamping and async clients - authentication

I have a restful api written in Go. I want to authenticate each request. To do so, the server and the client share a secret.
To authenticate a GET request to /foo/bar/, the client add a nonce parameter with a timestamp to the url, /foo/bar/?nonce=13899932199128265, and then add the hmac of data with the secret to the url. It gives something like /foo/bar/?nonce=13899932199128265&hmac=hd7nd7s9s702j
To verify the validity of an incoming request, the server verify that no requests from the client arrived after the time stamp and that the hmac is valide.
I believe it is a common way to authenticate requests. For instance, mtgox uses a similar process.
The problem that I have is that my client will likely require a list of urls [url1, ... urln] at the same time. In that case, nothing guarantee that the first request sent by the client will arrived first to the server. Indeed, any permutation of the requests will result in 403 errors.
My first question is simple: is that a real problem? Is it likely that request order will change during transport?
Second, is it entirely to the client to verify no 403 errors happen?
Is there better way to do?
Thanks a lot!

Related

Do we need to make the response secure?

Most of the time we are using JWT access token validation to make sure that the request to e.g. an API is secure. However do we need to make sure that the response that comes back from that system (or API) is secure enough? Do we need to be worry? and how should we mitigate it?
appreciate all kind of advice.
As usually with those things, the answer is it depends ;)
Who is the owner of the API that you're calling? If you're calling your own API then you can be pretty sure about the validity and safeness of the response. If you're calling a third-party API then you might add some checks. Maybe scan files for malicious code if you're downloading any files from that API? Or check whether the response is not trying to inject any code, etc. It might not be the easiest thing to do, though.
Are you using a secure connection to the API? If you use SSL then you're sure that no one has tampered with the response. Additionally you can verify certificate chains to verify that you're connecting to the right API endpoint and not to a malicious one. If you're not using SSL then you might want to verify the response from the API, whether it's been tampered or not. How to do that verification again might not be trivial, but maybe the response can be signed?
Where is the client which is talking to the API? If you have a backend client talking to an API then you should not worry that response might be altered at client side. If you have an SPA running in a browser, then the response might be altered by a man-in-the-browser attack. Such response can be altered even if you use SSL to connect to the API, as SSL is terminated in the browser and a compromised user-agent will grant the attacker access to the decrypted API response. You can also have an XSS attack which alters responses in your app. Again, to protect from that threat you would need responses to be signed, or have another way of verifying integrity.
One way of verifying integrity of a response is to use signed JWTs with asymmetric signing. The API can sign the response with its private key, and then you can verify whether it's not been tampered with. E.g. the JARM spec uses that for OAuth flow responses.

with https are GET requests less secure than Post Requests

As the title says. Should you pass an authentication token in the url of a GET request? What about man-in-the-middle attacks? Or Packet sniffing? All including the requests being wrapped with HTTPS
When you use https GET and POST are equally secure for man-in-the-middle attacks as the payload is encrypted and nobody except the receiver with the private key can see the data.
Using GET the urls visited are stored in the browser history and can also be shared (accidentally) with other pople (see also Session Hijacking). So I would not pass auth information as query parameter but use http header cookies or something wich is not stored in the browsers history. If you have to do it you should be sure that the auth information invalidated after some time.

Identity cookie expiry

How would I redirect to login page AUTOMATICALLY, if my Identity cookie has expired at "ExpireTimeSpan" value? I do understand there is an event "OnRedirectToLogin" but that doesn't get triggered unless a request comes through. Is there a way, I can redirect to login right after the cookie has expired rather than keep sending requests to verify it has timed out?
Unless I misunderstand, what you want is the server to reach out to the client, but standard client/server HTTP works the other way around. The client is supposed to send requests to the server, and at some point to get redirected if its authentication cookie has expired, but if the cookie expires and the client never ask the server for anything more ever, then it doesn't have to be told anything has expired. Communication the other way around, where servers notify clients can be achieved by several means but is to be reserved for very particular needs. Are you sure you need that?

Using socket io over http, is a secure log in procedure possible?

I have built a game server in nodejs using socket io.
I am planning to remove express and cookies from the authentication procedure and instead use webstorage and a client which attempts to log in during the socket io handshake.
However, I am using http and sending the user id and password in cleartext. Please, have mercy on me! I believe using https for the entire socket connection would add a huge overhead since updates are sent every 100ms. My current solution has worked for development, but I am sure it is insecure.
I should mention I have never set up/used https, so correct me if I am wrong regarding the overhead, which I know is a very debated topic. An ideal solution appears to be authenticating users over a https connection and then transmitting game state stuff over http, but I have no idea if or how this could be achieved.
Finally, I have 2 options for logging users in. I could allow the socket io connection on the server and just emit the log in credentials from the client. Then disconnect them if they are incorrect.
However, a cleaner solution would be to send the user id and pw in the http header for the handshake, and then authenticate the user from a socket.io middleware, but I am not sure if sending the data this way would be safe.
I do not think this is such a niche problem that a standard practice does not exist, however it may be to just use https. I believe there is no advantage to encrypting the users credentials as the data can still be snooped between the client and server. Any information on how I can achieve this is appreciated,
Or just point me in the right direction :)
Use one https connection for the login authentication and reply back to the client with a unique security token if the username/password is valid.
Use ordinary http connections for the rest of the dialog between client and server. Include the security token in the dialog if the client is requesting something that requires validation. Your client can store the security token in a cookie if you find that convenient, as the token can only be used for one session.
Have the server purge session tokens once a client signs off, or after the token has been idle for some period of time.
This is cheap and effective for medium-security applications. Variations on this scheme get used in many applications. It is not foolproof - a packet sniffer may be able to grab the security token in transit.
If the security token is constructed from a hash of the client IP address and a server timestamp, then it is easy for the server to validate the token in every message and very difficult for a 3rd-party to hijack the session.

Using a RESTful API - Is it secure?

We are partnering with a service provider which exposes their services via RESTful API.
We can authenticate with the API by passing a username and password as URL parameters.
Example: https://example.com/api/service.json?api_user=Username&api_key=Password
I know this is using SSL. However, since the username and password are part of the URL, couldn't this be intercepted by a third party?
No, a third party will only be able to see the destination (example.com). The rest of the URL is actually embedded inside the request.
It helps to understand the process of how an HTTP (or HTTPS) request is made.
determine protocol (in this case HTTPS, using port 443)
get IP address of server using DNS
establish a TCP connection to server (if SSL is involved, it's a bit more complicated)
issue a request to server on the new connection which will look something like
GET /api/service.json?api_user=Username&api_key=Password
Since the actual request is part of the encrypted data stream, there's no way for someone monitoring the connection to extract sensitive information.
The previous answers are both technically correct; if you're using HTTPS, the URL and querystring data will be encrypted prior to transmission and can be considered secure.
However, the fact that an API is asking for a username and password as querystring parameters may indicate a somewhat lax approach to security.
For example, many webservers will log the request querystring parameters by default , which means that your plain-text credentials might be lying around on disk somewhere (and many companies will store, or back up, webserver logs in insecure ways).
In short: passing credentials as querystring parameters isn't a security risk per se, but is generally a bad practice and may be symptomatic of larger security issues.
However, since the username and password are part of the URL, couldn't
this be intercepted by a third party?
The URL is sent under encryption as well. In other words, the process that secures the channel occurs before the URL is sent to the server.
You're safe.