Firebase Admin SDK Leaks: How Service Account Keys End Up in Public Repos
Introduction to Firebase Admin SDK Leaks
Firebase Admin SDK leaks occur when service account keys are exposed in public repositories, allowing unauthorized access to Firebase resources. This happens when developers accidentally commit their service account keys to their version control system, making them publicly accessible. The main question is: how do service account keys end up in public repos? The answer is simple: when developers forget to add their service account keys to their .gitignore file or accidentally commit them.
The Firebase Admin SDK is a powerful tool for managing Firebase resources, but it requires a service account key to authenticate and authorize actions. When a service account key is exposed, an attacker can use it to access and manipulate Firebase resources, including databases, storage buckets, and authentication systems.
How Service Account Keys are Exposed
Service account keys are typically stored in a JSON file, such as serviceAccountKey.json, which contains the private key and other authentication credentials. When a developer creates a new Firebase project, they are prompted to download this JSON file, which they then use to authenticate their Firebase Admin SDK.
However, when a developer commits this JSON file to their version control system, such as Git, it becomes publicly accessible if the repository is public. This is because Git repositories are designed to track changes to code and configuration files, including sensitive files like service account keys.
For example, consider the following code snippet, which demonstrates how to use a service account key to authenticate the Firebase Admin SDK:
const admin = require('firebase-admin');
const serviceAccount = require('./serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://.firebaseio.com',
});
In this example, the serviceAccountKey.json file is stored in the same directory as the code file, and is loaded using the require function. If this code is committed to a public repository, the serviceAccountKey.json file will also be committed, exposing the service account key.
Consequences of Service Account Key Exposure
When a service account key is exposed, an attacker can use it to access and manipulate Firebase resources. This can have serious consequences, including:
* Unauthorized access to sensitive data, such as user authentication credentials or database records
* Manipulation of Firebase resources, such as creating or deleting databases, storage buckets, or authentication systems
* Financial losses, such as unexpected charges for Firebase services or damage to reputation
For example, consider the following code snippet, which demonstrates how an attacker can use an exposed service account key to access a Firebase Realtime Database:
import firebase_admin
from firebase_admin import credentials, db
cred = credentials.Certificate('serviceAccountKey.json')
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://.firebaseio.com',
})
ref = db.reference('path/to/data')
print(ref.get())
In this example, the attacker uses the exposed service account key to authenticate the Firebase Admin SDK, and then uses the db.reference function to access a Firebase Realtime Database.
Preventing Service Account Key Exposure
To prevent service account key exposure, developers can take several steps:
* Add the serviceAccountKey.json file to their .gitignore file, so that it is not committed to the version control system
* Use environment variables or a secure secrets management system to store the service account key, rather than storing it in a file
* Use a tool like SecuriSky to detect and alert on exposed service account keys
For example, consider the following code snippet, which demonstrates how to use environment variables to store a service account key:
export SERVICE_ACCOUNT_KEY=$(cat serviceAccountKey.json)
const admin = require('firebase-admin');
const serviceAccount = JSON.parse(process.env.SERVICE_ACCOUNT_KEY);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://.firebaseio.com',
});
In this example, the service account key is stored in an environment variable, rather than in a file. This makes it more difficult for an attacker to access the key, even if they gain access to the code repository.
Quick Fix Checklist
serviceAccountKey.json to .gitignore fileTry it free
Scan your app for these issues now
Paste your URL and get a full security, performance, and SEO report in under 2 minutes — no signup required.
Run a free scan