Home > OS >  How to manage API keys for npm packages that require key on the client-side code?
How to manage API keys for npm packages that require key on the client-side code?

Time:11-04

It's a hot debate on how to securely handle API Keys.

And almost all of us know that it's the best solution to have them stored on the server side, and never exposed in client-side applications.

Our clients can send requests to our APIs, and our APIs can act as proxy to send/receive data to/from the third party API and return the response back to our client.

However, there are some third party SDKs that you can integrate into your client-side app and they also have their API Keys.

For example, Zoom has SDKs for Web, Android, iOS, Windows, etc., or Pusher has Pusher Key.

When you want to work with these libraries, you CAN NOT send request to your API to hide API Key. You have to initialize these libraries in your client-side code (react for example).

An example from Zoom to join a meeting inside your web app:

client.join({
    apiKey: apiKey,
    signature: signature,
    meetingNumber: meetingNumber,
    password: password,
    userName: userName
})

What are the best practices to secure API Keys for client-side SDKs and libraries?

CodePudding user response:

What do you want to secure exactly? I assume you want to avoid someone from misusing your API key, but you should ask yourself, from what security risk or threat do you want to protect?

You should also understand what kind of API key are you dealing with, as not all of them are intended for the same use-case and could 'offer' different level of security. For example, you could have an API key in the form of a personal access token (in GitHub, for instance), where the token is directly tied to a user/employee and should be considered a secret, or you may have an API key in the form of a machine token that it's tied to your organization or your repository (still in GitHub, for instance) and that can be configured with different permissions (read-only, read-write).

It is also possible that the API key can be configured and restricted to some clients, according to the possibility of the client itself. For example some of the Google Maps APIs allow you to configure a trusted origin that it is allowed to perform requests using your specific API key, however this protection works by checking the referrer header of the request and it could be spoofed by arbitrary clients. Browsers should still honor the convention and send the correct referrer, protecting you from people that want to use your API key on their website.

Another example in the mobile application world: there are some vendors that allow you to bind your API key to a specific package name that it is then validated at runtime by the vendor's SDK, however this kind of protection is usually as a licensing mechanism, to avoid developers to configure for free an SDK with a leaked API key.

Most generally, if the API key is intended to be used on public clients, then the developers of the API already considered the threat of having this leaked and you should not have a repercussion. This means that you will be covered from huge API usage billings or from rate-limit/usage quota limit (but better check yourself!).

The general rule is to always check the developer's documentation of the application you're trying to configure and see how to create a proper API key for your use-case and if it's fine for you to have this 'leaked' from your client. Additionally, if the API key allows you to configure permission, remember to follow the Principle of Least Privilege.

Another golden rule is to always threat model your implementation:

  • What are the capabilities of the API key?
  • What is the worst an attacker can do if they access the API key?
  • Am I protecting myself from these threat? How? Can I put more controls or monitors on back-end side (i.e. notification on high usage, etc)?

Finally, if your API key need to be kept secret, then you must not use this on a public client, no matter how hidden it is. There will always be at least one person able to retrieve it (And don't rely on client-side check either!). In this case what you want is probably to have your own back-end service responsible both for querying the APIs using the secret API key and for authenticating and authorizing your customers/users, and also to implement additional security measures like rate limit.

One thing I found very helpful is to always document any generated/used API key and its capabilities along with the threats of having them leaked and some preventive measures to minimize the risk.

Hope this help.
Best,

CodePudding user response:

Your Problem

When you want to work with these libraries, you CAN NOT send request to your API to hide API Key. You have to initialize these libraries in your client-side code (react for example).

What are the best practices to secure API Keys for client-side SDKs and libraries?

Well you found yourself a very hard problem to solve (but not impossible to some degree), because once the API Key is in the client side it's public. So, no matter how well you hide it will always be possible to retrieve it on a browser or mobile app.

Web Apps

On browsers is very trivial to get hands on the API key, just open the developer tools and in the network tab look for the request you are interested in extracting the API key and click on it to inspect the request headers.

Mobile Apps

In mobile devices id more laborious to extract an API key from a mobile app, but not that difficult has many may think.

JNI/NDK - Hide API Key in Native C Code

For example, you can hide the the API key in C native code via JNI/NDK:

Using Android Studio 2.2 and higher, you can use the NDK to compile C and C code into a native library and package it into your APK using Gradle, the IDE's integrated build system. Your Java code can then call functions in your native library through the Java Native Interface (JNI) framework.

This approach aims to protect the AP/i key from being extracted from your mobile app binary via static binary analysis, as exemplified in this repo and blog post I wrote:

During this article we will use the Android Hide Secrets research repository that is a dummy mobile app with API keys hidden using several different techniques.

Extract the API Key hidden in Native C Code with a MitM Attack

In the above blog post the API key hidden in the source code with JNI/NDK interface was not possible to extract via static binary analysis, but it was easy to extract with a MitM attack as I demo in the article Steal that Api Key with a Man in the Middle Attack:

In order to help to demonstrate how to steal an API key, I have built and released in Github the Currency Converter Demo app for Android, which uses the same JNI/NDK technique we used in the earlier Android Hide Secrets app to hide the API key.

So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.

Prevent MitM Attack with Certificate Pinning

The first thing one can do to prevent a MitM attack is to use certificate pinning and I wrote about how to do it in the article Securing HTTPS with Certificate Pinning:

In order to demonstrate how to use certificate pinning for protecting the https traffic between your mobile app and your API server, we will use the same Currency Converter Demo mobile app that I used in the previous article.

In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.

I see the smile on your face now, but will not be for long because certificate pinning can be bypassed.

Bypassing Certificate Pinning

You can do it repackaging the mobile app without pinning or by using an instrumentation framework at runtime to disable it.

Repackaging the mobile app to bypass pinning

This is not hard to achieve when you have the correct tools and open source is full of them. I wrote how to do it in the article Bypassing Certificate Pinning

In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates. This will allow us to bypass certificate pinning.

Using an Instrumentation Framework to bypass pinning

This is my preferred method and my instrumentation framework of preference is Frida, and guess what, I also have an article on it with the title How to Bypass Certificate Pinning with Frida on an Android App to show you how to do it:

Today I will show how to use the Frida instrumentation framework to hook into the mobile app at runtime and instrument the code in order to perform a successful MitM attack even when the mobile app has implemented certificate pinning.

Bypassing certificate pinning is not too hard, just a little laborious, and allows an attacker to understand in detail how a mobile app communicates with its API, and then use that same knowledge to automate attacks or build other services around it.

Possible Solutions

You may employ an array of different approaches and techniques to defend your API server and mobile app, but give preference to use a security solution that spans both the mobile/web app and API server.

The solution(s) to use will depend on your threat model, your budget and your resources and I will give you below pointers to some options.

For Mobile Apps

I recommend you to read this answer I gave to the question How to secure an API REST for mobile app?, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution.

For Web Apps

You can learn some useful techniques to help your API backend to try to respond only to requests coming from what you expect, your genuine web app, and to do so I invite you to read my answer to the question Secure api data from calls out of the app, especially the section dedicated to Defending the API Server.

Do You Want To Go The Extra Mile?

In any response to a security question I always like to reference the excellent work from the OWASP foundation.

For APIS

OWASP API Security Top 10

The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.

For Mobile Apps

OWASP Mobile Security Project - Top 10 risks

The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.

OWASP - Mobile Security Testing Guide:

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

For Web Apps

The Web Security Testing Guide:

The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.

  • Related