We recently participated to the DZone mobile apps development guide to highlights some of the key best practices when dealing with API keys and tokens. Below is an excerpt, the full article is available on DZone!
Modern applications, both web-based and native, rely on APIs on the backend to access protected resources. To authorise access those APIs, a request must include some kind of access token or key. This article focuses on security best practices for access token management, for the API providers and application developers alike.
Let’s talk about trust first!
When dealing with security, a single rule prevails: trust no one. If you’re an API provider, you can’t trust that the application invoking the APIs is the one you expect, that the token you received has not been stolen, or that the communication between client and the server has not been intercepted. On the client side, you can’t trust that the application will not be decompiled, exposing embedded secrets, that the application storage will not be compromised through an XSS attack, or that your users are not being fooled into submitting forged requests.
This implies that you must put in place proper measures to securely obtain, store and manage the security tokens required to invoke backend APIs.
Additionally, you may think your APIs are safe if you have never publicly advertised them. To you, they feel private, because they are only used by your enterprise applications. However, if they can be used from a mobile application, they are on the public internet, and thus public. Any API exposed outside your enterprise network must be considered public.
Obtaining tokens and API keys
When it comes to using an API, you are usually offered two choices: pass a static piece of information together with the API call, or obtain that piece of information dynamically prior to invoking the API. This piece of information is usually an access token or API key. BasicAuth is still used for some APIs for legacy reasons, but is deprecated as a mainstream solution.
When designing the security aspects of your API, you must choose wisely how your API consumers access it. Like usually with security measures, the induced risk is the key factor to take in account. Securing an API which only allows to consult weather data is very different from securing a banking payments API.
While using an API key is easier for the developer, it does not give the same level of security as an access token obtained with two-factor user authentication and the proper identification of the client application. Moreover, an API key does not carry any information about the user and can’t be used at the backend level to decide which operations the API consumer is allowed to invoke. Finally, API keys never expire, unless revoked by the API provider.
OAuth was created to address these drawbacks: the application accessing the resource is known (using client application credentials), the API provider can define scopes to limit the access to certain operations (you can GET a catalog entry, but you can’t PUT a new catalog entry, even with a valid token), and tokens have a limited lifetime.
Token management recommendations
Beware of OAuth app credentials leaks
Storing your application code in Github? Are your OAuth app credentials stored there as well, and in particular the client secret? This is the number one source of credentials leaks today. If those credentials are stolen, anybody can pretend to be you. If you believe credentials could have been compromised, regenerate them immediately.
Don’t hardcode tokens in applications
It can be tempting to simplify code to obtain a token for a long period of time and store it in your application. Don’t. Do. That.
Treat tokens as you would treat passwords.
They are the door key! Tokens and API keys allow anybody who has them to access a resource. As such, they are as critical as passwords. Treat them the same way!
OAuth is not an authentication protocol!
OAuth is about delegating access to a resource. It is not an authentication protocol (despite the name, mind you). Think of tokens as hotel cards: you need to authenticate yourself to obtain the hotel key, but once you have it, in no way does it prove who you are. API providers must not rely on token possession as a proof of identity, as proven by this recent user information leakage.
You really should look at OpenID Connect (OIDC), a complementary specification, rather than trying to implement authentication on top of OAuth yourself. OIDC allows a user to share some aspects of their profile with an application, with no need to share their credentials.
Beware of what you store in JWTs and who has access to them
JWTs can store plenty of information in the form of claims, and can easily be parsed if captured (unless they are encrypted). If you are using JWTs to carry information that is only useful to the backend services, you can take a different approach, which is provided by many API security gateways OOTB:
- Use an opaque string or basic JWT between the client and the backend
- At the backend, validate the request and inject a new JWT, with a payload containing the claims that are consumed downstream.
If you want to use the same token across the entire flow and it can potentially carry sensitive information, encrypt the token payload. This said, never use a JWT to carry user’s credentials, such as passwords!
Validate JWTs thoroughly
When you receive a JWT on the server-side, you must validate its contents thoroughly. In particular, you should reject any JWT that does not conform to the signature algorithm you expected, that uses weak algorithms or weak asymmetric/symmetric keys for signing. Additionally, you must validate all claims, expiration date, issuers, and audience.
Certain libraries and tools do this for you, others need to be configured properly first, and some only do partial checks. Take the appropriate measures depending on the libraries you use.
The complete article and more useful information about mobile apps development is available here: https://dzone.com/guides/dynamic-web-and-mobile-application-development. Enjoy!