7

I went through the question Securing a JavaScript Single Page App with RESTful backend that has discussions / options around securing a Javascript client side app that invokes RESTful APIs.

However, from the discussions, it is not clear as to how the "shared secret" that is used for computing the HMAC is kept safe at the client side. Storing such a Shared secret in either a Cookie (which is accessible from scripts) or even in local storage is no-good as these are vulnerable to leaks. Are the keys generated dynamically so that every round trip to the server returns a new key that is to be used for computing the HMAC for the next round trip ?

mithrandir
  • 283
  • 2
  • 6

2 Answers2

2

My seven cents here...Nothing can be 100% secure. But 99% is doable. You could use the HMAC or even an RSA algorithm with JWTs (I'm assuming you're well versed on JWTs. If not, here is a nice article). The token is generated using said algorithm once on every successful user login. The secret is only stored server side, but there have been uses of client nonces (read more here). You could pass the secret between client and server, but it would have to be dynamic and the re-generation of tokens could impact performance. You can turn off access to cookies via scripts by enabling the HttpOnly property on the cookies that are issued from the server. You could also set short expiration times for tokens so in case of theft, they expire shortly after. Make sure to establish TLS 1.0 or better for any and all communications between client and server, and maybe some monitoring and alerting on events generated from the app. All the best :)

  • You're not addressing how the "shared secret" is kept safe on the client side, e.g. where should it be stored. If you're suggesting to store it the cookie, and enabling HttpOnly, then the client is not going to be able to read the secret from the cookie. – HTLee Mar 14 '18 at 04:24
  • There isn’t a good way to keep the secret safe on the client side. You’re right, in that HttpOnly cookies may be a bad idea since they wouldn’t be readable, but unless the client side is protected against XSS, this would result in stolen cookies. –  Mar 14 '18 at 04:41
2

First, a few things:

  • There is no shared secret in Thomas Pornins answer to the linked question. The server uses a secret only it knows to compute the HMAC. The client then gets that HMAC, and sends it to the server on every reqeust as an authentication token. The server can check it by recalculating it with the servers secret. Note that the client never calculates a HMAC.
  • Rather than implementing this yourself, you probably want to go with an existing solution, like JWT.

But still, the HMAC or JWT or whatever needs to be kept safe client side. Personally, I'd put it in local storage but a cookie could also work. You rule these out as they are vulnerable to "leaks". It might be true that malware running as root, or someone with physical access, could steal these. That's a risk. But here's the thing: All login system, from old fashioned session IDs to modern JWTs, works by letting the client store a secret. If you can't accept that risk, you can't have login, and you'll need to have the user retype the password on every request. (But who knows, malware that can read local storage could potentially read keystrokes as well...)

Not sure exactly what you mean with using a new secret for every round trip, but it couldn't solve the above dilemma. At the first request, the client authenticates itself with a password and gets a secret it can use for future authentication in return. At the next request, the client has to authenticate itself again. Either, it has saved the secret and can use that. Or it has not, and then the user has to retype the password.

Anders
  • 64,406
  • 24
  • 178
  • 215