views:

74

answers:

2

I like the way Google Maps' api is consumed, using a script include, but I'm worried:

My api is "semi-private", that is, accessible over the internet but should allow for secure transmission of data and some kind of authentication. The data should remain private over the wire, and one consumer shouldn't be able to get at another's data.

How can I use SSL and some kind of authentication to keep the data secure, but still accessible "horizontally" from a plain HTML page with no server-side proxy required? Do I need to manage keys? How will the keys be posted to the server without being intercepted? Can I use OpenId (or some other 3rd-party authentication) to authenticate api users, or do I have to create my own authentication mechanism? I've been all over Google and can't find a good guide to designing and deploying my API securely.

Right now I'm using REST and AJAX to consume them, but cross-domain calls are impossible. Any help or a pointer in the right direction would be much appreciated.

+3  A: 

I'd probably use a dynamically-generated script tag with an SSL URL that included a key in the query string that was public-key encrypted. The server would use the private key to decrypt the query string parameter and return script that included the relevant information (or didn't, if the key was invalid). Or something along those lines. But I'll admit that I haven't actually had to do it in practice.

I'd also look for prior art, like Amazon's S3 service.

So:

  1. User provides secret
  2. Client-side code uses public key to encrypt the secret
  3. JavaScript appends a script tag that includes the URL
  4. Server handles the script request, decrypts the secret, checks it, and sends back the relevant response.

You may well need two cycles, because otherwise the request to the server could be re-used via a man-in-the-middle attack. That would be:

  1. JavaScript appends a script tag that requests a unique key (probably with some confounding information, like the source IP and some random further key)
  2. Server responds with a one-time key tied to that IP
  3. User provides secret
  4. Client-side code uses public key to encrypt the secret, including the unique key from #1
  5. JavaScript appends a script tag that includes the URL
  6. Server handles the script request, decrypts the secret, checks it, and sends back the relevant response.
  7. The response could well be encrypted (to some degree) using the random key included in #1

None of which I've actually done. (Or have I? BWAa-ha-ha-ha...) FWIW.

T.J. Crowder