8

Many APIs protected with API keys only use the secret key (i.e. a password) without something like an account ID or username.

For example Stripe API uses the secret key as the username in Basic Auth, leaving the password blank:

curl https://api.stripe.com/v1/charges \
   -u sk_test_BQokikJOvBiI2HOWgH4olfQ2:

How does this work server-side? Does it look for the secret in a table with the secrets as primary keys, in plain text? What happens if this table is leaked?

Why is this better than to use a account_id:secret_key combo in the authentication? You can then store bcrypt(secret_key) instead of the secret_key in plain text, using the account_id as the primary key.

Related, but not the same

4
  • Even if you do an account_id:secret_key authentication approach, the secret_key can still leak through the headers. Right?
    – Limit
    Commented Apr 12, 2018 at 14:00
  • ...assuming both schemes are using https
    – Victor
    Commented Apr 12, 2018 at 14:05
  • 1
    From a security perspective, I'm not sure this is better or worse at all. It was just a decision made by whoever architected the system. And a database can still index a hash, so there's no reason the primary key couldn't be the hash, a random id, or even just a number.
    – nbering
    Commented Apr 12, 2018 at 16:44
  • It's worse. nordicapis.com/…
    – starflyer
    Commented Jul 20, 2021 at 20:49

3 Answers 3

1

As nbering already pointed out, there is nothing making this less secure. It's not that hard to search the database for hash(secret) instead of account_id.

From an attackers perspective, guessing an API key is pretty hard (most of them are considerable in size). Using the scheme account_id:secret (assuming secret is the API key, not the user password) certainly adds even more security, but to no practical effect (account names are rarely a secret, so obtaining them is not too hard. No attacker would randomly guess one, in addition to guessing a key).

Furthermore, think about where those API keys are used. Most likely in automated processes (i.e. a python script doing some work). Requiring the developers to add an account name, forces them to write it into the code or some config file. In case of an attack, I'd rather lose my API key, which I can easily revoke and exchange for a new one, instead of losing my account_id and the API key. Using the account_id, an attacker only needs the password to hijack your account, which is probably way less secure compared to a long API key (so academically speaking, adding account_id even weakens your security, while omitting it doesn't really lower it).

2

Those API keys are often called tokens. They are often assumed to have a rather short lifetime and are more or less used as a high level session id. It is not a true session because they are used for stateless requests and only carry user identification. But their lifetime generally spans from a few hours to several days. More, they are never a primary access key, so if the token database get compromissed, it is immediately emptied and users ask for new API keys.

0

Many APIs protected with API keys only use the secret key (i.e. a password) without something like an account ID or username.

API keys or commonly known as tokens, are provided after successful authentication through proper account_id and password. This can be done during API calls so the client provides once its credentials to obtain a key which is in turn used for the subsequent API calls. The same credentials are used to revoke or renew a token.

Why is this better than to use a account_id:secret_key combo in the authentication?

APIs are meant to allow communication between systems and not designed to have direct interaction with user, in my opinion an account id has different meaning then identifying a (client)system.

However the main reason why is better to use a token instead of account_id/password is to avoid frequent circulation of the password over the wire. Remember The stateless nature of API, it makes the client to provide credentials on each request.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .