Search code examples
jsonapisslaccess-tokenapi-key

How do we deliver the API keys and secret tokens securely over the wire to the users?


How can we prevent a public API to reveal master API keys/credentials and secret tokens?

I am currently working on a webapp with some public API which should use API keys and secret tokens and were looking for a way to create a very secure API and took some look at some of the APIs of the biggest platforms, for example SoundCloud.

I read some guides (like https://github.com/interagent/http-api-design) about good (restful) API design, but they give not much information about the security (API keys and tokens) and how they should be retrieved or created in public APIs.

Take a look at https://a-v2.sndcdn.com/assets/sc-q9dV-e79e4b4a.js and search for b45b1aa10f1ac2941910a7f0d10f8e28

This is the master API key of SoundCloud.

Some of their URLs look like this:
https://api.soundcloud.com/tracks/id/stream?client_id=client_id
https://api.soundcloud.com/tracks/id/stream?secret_token=secret_token&client_id=client_id
https://api.soundcloud.com/playlists/playlist_id/?secret_token=secret_token&client_id=client_id

I know that many tools out there are already using this key for fetching/downloading all the songs from a SoundCloud user.

Also all their private and secret widgets reveal the secret tokens, also in the requests and in the sourcecode. They are hardcoded in the JavaScript code of the embed codes.

The problem consists for some years and the developers seem to have no experience with secure APIs http://tunelab.com/2011/08/04/this-is-the-problem-with-soundcloud/

How can such APIs using JavaScript and JSON prevent to reveal these tokens and credentials?

My thoughts about this:

  • the master API key should be only accessible through/from soundcloud.com
  • there should be some sort of domain/IP blocking/restriction//firewall for all API keys
  • use OAUTH for all API keys, not just a simple JSON API with no authentication
  • dynamically generate one-time (secret) tokens, do not reuse the same token all the time
  • dynamically get the API keys and tokens from the SoundCloud server instead of putting them into the embed codes and requests
  • use some sort of steganography

When I read that SoundCloud is the biggest music community and big music labels upload their songs from new or upcoming albums (even as private songs and post them with a widget on websites, the secret tokens are also revealed) it seems, that the team behind SoundCloud does not want to protect their users against piracy/stealing of songs and is not willing to create a secure API.

What do you think about this critical situation on soundcloud.com and how could a JavaScript/JSON API be much more secure/secured the right way without revealing any critical data like tokens and API keys? For example using AJAX and retrieving the API key and token after the website is loaded? How do Spotify and other streaming platforms protect the data which they are streaming and get the token and API key? Is storing these information in a URL or request URL secure at all?

How can I securely send the API key and secret token to my users over the wire using JavaScript, HTML, AJAX and PHP?


Solution

  • how do I deliver the API keys and secret tokens securely over the wire to the users?

    There is only one reliable way: use HTTPs for your web site to allow the users to retrieve the key.

    Then during the API calls HTTPS is no longer required. Your users can use HMAC authentication to hash the key with a shared secret.