Ask HN: How do you secure a client side (JavaScript) API?
Ok, so here's the background. I am working on a widget, which can be plugged into any website add some functionality to it. In order to authenticate against the API, I provide an client token, and a secret.
When the client widget authenticates it passes a client generated challenge string, the client token, and a hash which is calculated as hash(challenge+secret). Everything except the secret is available to the client.
This scheme is currently vulnerable to copying the challenge string, client token and hash and then reused on any other site. Currently, the only solution I can think of to resolve this is to use short lived (say 20 mins) server generated challenge strings and use those to generate a hash.thus only the client token and hash would be available to the client and that will only be valid for about 20 mins or so.
Is there any better way to do this?
3 comments
[ 2.0 ms ] story [ 20.8 ms ] threadOff the top of my head, one option would be to embed the domain name into the hash so that you can validate it is from the domain that is authorized to use the token. If it comes from any others send back an error. You might have to provide a mechanism for people to test on localhost or on development/staging domains but that seems minor overall.
Without being able to verify that the request is originating from the domain that is specified in the hash, it is still susceptible to the same attack. The hash, challenge and token are all still available client-side.
Basically the hash might say that it is from abc.com, but it could really be from any domain. So yes while the token might match the hash, if both the token and hash are copied it does not help.
For what it is worth, on our client accessible API, we require clients to authenticate and then send in the token we return through the http header for each request, and the token is reset often. The token is a hash of a few client identifiers, but it is calculated and sent to the client so the client never calculates it. We only allow https for the API. This seems to be a fairly common pattern.
EDIT: add link
This method is similar to how we calculate our token:
http://billpatrianakos.me/blog/2013/09/12/securing-api-keys-...