Read-only impact assessment tool for leaked/exposed Firebase credentials (defensive security).
Project description
firebase-cred-impact
A read-only, safe-by-default tool for determining the blast radius of an exposed / leaked Firebase credential during an authorized security assessment. Ships as a Python CLI and a zero-build, browser-only web UI.
Purpose: identify what the credential can access so the product team can remediate immediately. It is not an exploitation tool. It never enumerates, downloads, or dumps data, and every operation that could create, modify, or delete a resource is disabled unless you pass an explicit flag.
Key context: a Firebase Web API key is a client identifier, not a secret. Its real impact is governed by the project's Security Rules and enabled sign-in providers — which is exactly what this tool measures.
What it does
Runs a 10-phase, non-destructive assessment against a Firebase project using the exposed config and reports precisely which surfaces are reachable without authentication:
- Credential Identification — validate the API key, record all metadata.
- Project Fingerprinting — which services are reachable (headers/metadata).
- Authentication Assessment — provider discovery, anon/email sign-up config, password-reset & email-verification endpoint availability.
- Firestore Assessment — unauthenticated read/write posture (single-doc probes).
- Realtime Database Assessment — availability, public read/write (shallow).
- Cloud Storage Assessment — bucket reachability, listing, read, upload, delete.
- Cloud Functions Assessment — characterize supplied/known HTTPS endpoints.
- Security Rule Validation — infer whether rules are restrictive.
- Privilege Matrix — condensed per-service permissions table.
- Evidence Collection — write the deliverables (below).
Safety model
| Operation | Default | Flag required |
|---|---|---|
| Read/reachability probes (all services) | ✅ enabled | — |
| Auth account creation (anonymous / email sign-up) | ❌ disabled | --active |
| Firestore / Realtime Database write probe | ❌ disabled | --active |
| Cloud Storage upload / delete probe | ❌ disabled | --storage-write |
| Cloud Functions brute-force | 🚫 never | — |
Mutating probes create a single, clearly-labeled, disposable resource and delete it immediately. The API key is masked in every artifact and response bodies are truncated so bulk data can never be captured.
Install (CLI)
Requires Python 3.12+.
cd tools/firebase-cred-impact
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e .
CLI usage
Read-only assessment from individual values:
firebase-impact assess \
--project-id your-project \
--api-key AIzaSy... \
--output ./assessment-out
From a firebaseConfig JSON object (inline or @file):
firebase-impact assess --config-json @firebaseConfig.json -o ./assessment-out
Assess specific, known HTTPS Cloud Functions (never brute-forced):
firebase-impact assess -p your-project -k AIzaSy... \
--function api --function webhook --region us-central1
Enable mutating probes (only within an authorized engagement):
firebase-impact assess -p your-project -k AIzaSy... --active # auth + firestore/rtdb writes
firebase-impact assess -p your-project -k AIzaSy... --storage-write # storage upload/delete
Output artifacts
Written to the --output directory: report.md, report.html, summary.json,
raw_results.json, and logs/assessment.log. Each report includes an Executive
Summary, Risk Rating, Affected Services, Evidence, the Privilege Matrix,
Recommended Mitigations, and non-sensitive Attribution Identifiers (project
id, app id, auth domain, storage bucket, database URL, discovered function
endpoints, console URL) to help locate the affected project.
Web UI (no build, no backend)
Open web/index.html directly in a browser (or serve it statically) to run the
browser-feasible read-only checks entirely client-side — nothing is sent to any
server other than the target Firebase project's public endpoints.
# open directly…
xdg-open tools/firebase-cred-impact/web/index.html
# …or serve the folder
python3 -m http.server -d tools/firebase-cred-impact/web 8080 # then visit http://localhost:8080
Because browsers enforce CORS, some Google endpoints (Identity Toolkit, Realtime Database, Cloud Storage, Remote Config) can be checked directly from the page, while others (Firestore REST, cross-origin Cloud Functions) may be blocked. When a check can't run in the browser, the UI degrades gracefully and shows the equivalent CLI command to run instead.
Read-only by default. With no options ticked the page never creates, modifies, or deletes anything. Two opt-in checkboxes mirror the CLI's mutating flags:
- Active (
--active) — creates then immediately deletes a disposable auth account (email + anonymous sign-up), a Realtime Database node, and a Firestore document to measure write access. - Storage upload/delete (
--storage-write) — uploads then deletes a single disposable object.
Ticking either one and pressing Run opens an authorization disclaimer that must be explicitly accepted before any write is attempted; cancelling performs no probes. Every mutating probe cleans up the resource it created. Browser CORS still blocks some write endpoints (Firestore/Storage), and those degrade to the equivalent CLI command. The key entered on the page is never stored or transmitted anywhere except the target project's own public endpoints during the live checks.
Development
cd tools/firebase-cred-impact
python3.12 -m pip install -e ".[dev]"
pytest # offline smoke tests (import + CLI --help)
ruff check firebase_impact # lint
black --check firebase_impact # formatting
mypy firebase_impact # type check (advisory)
Build a release artifact
The CLI is a standard PEP 517 Python package. Build the sdist + wheel with:
cd tools/firebase-cred-impact
python3.12 -m pip install --upgrade build
python3.12 -m build # writes dist/*.tar.gz and dist/*.whl
Attach the files in dist/ (e.g. firebase_impact_tool-1.0.0-py3-none-any.whl
and firebase_impact_tool-1.0.0.tar.gz) to a GitHub Release. Install a released
wheel with pip install firebase_impact_tool-1.0.0-py3-none-any.whl.
Releasing
Releases are automated by GitHub Actions
(.github/workflows/release.yml). Because
this repository ships two independent packages, each is released with its own
tag prefix — this package uses firebase-impact-tool-vX.Y.Z.
- Update the version in
firebase_impact/__init__.py(__version__) and add aCHANGELOG.mdentry. - Commit the changes.
- Push a version tag:
git tag firebase-impact-tool-v1.2.3 git push origin firebase-impact-tool-v1.2.3
- GitHub Actions builds the sdist + wheel, runs
twine check, generatesSHA256SUMS, and creates a GitHub Release with auto-generated notes and the assets attached. - A final version (
X.Y.Z) is published to PyPI; a pre-release such as1.2.3rc1is published to TestPyPI. Both use OIDC Trusted Publishing (no API tokens).
Alternatively, run the Manual Release workflow from the Actions tab
(workflow_dispatch) to bump the version, test, build, and release — with
prerelease / draft / publish-to-index toggles.
One-time setup: on PyPI (and TestPyPI) add a Trusted Publisher for this package pointing at repo
ajtazer/ajtazer, workflowrelease.yml, and environmentpypi-firebase-impact-tool(respectivelytestpypi-firebase-impact-tool). Each package uses its own environment so the two configs stay distinct — PyPI rejects duplicate pending-publisher configs.
How impact is assessed
The tool reasons from observed HTTP behavior, not assumptions:
- API-key liveness is confirmed via Identity Toolkit
getProjectConfig: a dead key returnsAPI_KEY_INVALID; a live key is accepted or returns a different, non-key error. - Read posture is probed with the smallest possible request — a single
non-existent document (Firestore), a
?shallow=truekeys-only root read (RTDB), or amaxResults=1listing / single-object metadata GET (Storage). A200implies unauthenticated read;403implies rules deny it;401implies auth is required;404distinguishes "reachable but empty". - Write posture is only tested with
--active, by creating one clearly-named disposable resource and deleting it immediately. - Auth configuration is inferred from error codes on dry Identity Toolkit
calls (e.g.
OPERATION_NOT_ALLOWED⇒ sign-up disabled) so no accounts are created unless--activeis set. - Security-rule posture (Phase 8) is derived from the read/write verdicts above — the tool never attempts to bypass rules.
- Results are condensed into a privilege matrix and mapped to an overall risk rating (accessible-write ⇒ Critical, accessible-read/self-service-auth ⇒ High, reachable-but-restricted ⇒ Low/Medium).
Responsible use
Use only against projects you are authorized to assess. Keep it read-only
unless your rules of engagement explicitly permit mutating probes. Never commit
real credentials or sample outputs — the included .gitignore blocks common
secret/output filenames.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file firebase_impact_tool-1.0.0.tar.gz.
File metadata
- Download URL: firebase_impact_tool-1.0.0.tar.gz
- Upload date:
- Size: 39.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b393d9efc5aa2ce521110f2a01427da951cc74ca7a0622af5529d7953221773
|
|
| MD5 |
46b6edbffea9dcba2be31465724d12f7
|
|
| BLAKE2b-256 |
f1190e0d171769228d6336eebb3b6e7be8386504ca9bc865d22cee898a9767b5
|
Provenance
The following attestation bundles were made for firebase_impact_tool-1.0.0.tar.gz:
Publisher:
release.yml on ajtazer/ajtazer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firebase_impact_tool-1.0.0.tar.gz -
Subject digest:
2b393d9efc5aa2ce521110f2a01427da951cc74ca7a0622af5529d7953221773 - Sigstore transparency entry: 2211717485
- Sigstore integration time:
-
Permalink:
ajtazer/ajtazer@0f8300ded775c4f990f984dab0c89e7d46de4cae -
Branch / Tag:
refs/tags/firebase-impact-tool-v1.0.0 - Owner: https://github.com/ajtazer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0f8300ded775c4f990f984dab0c89e7d46de4cae -
Trigger Event:
push
-
Statement type:
File details
Details for the file firebase_impact_tool-1.0.0-py3-none-any.whl.
File metadata
- Download URL: firebase_impact_tool-1.0.0-py3-none-any.whl
- Upload date:
- Size: 45.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa8e1cc918cd183e6e2ad01bd35f3b42586d6b10e2f89e488c6090e0b648b84f
|
|
| MD5 |
a7d1c940df819ce1857e22734488afdd
|
|
| BLAKE2b-256 |
2dd690b795f474d99043895cd8459929f7f01ad77f5a760b9f8e756e09f561bc
|
Provenance
The following attestation bundles were made for firebase_impact_tool-1.0.0-py3-none-any.whl:
Publisher:
release.yml on ajtazer/ajtazer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
firebase_impact_tool-1.0.0-py3-none-any.whl -
Subject digest:
fa8e1cc918cd183e6e2ad01bd35f3b42586d6b10e2f89e488c6090e0b648b84f - Sigstore transparency entry: 2211717514
- Sigstore integration time:
-
Permalink:
ajtazer/ajtazer@0f8300ded775c4f990f984dab0c89e7d46de4cae -
Branch / Tag:
refs/tags/firebase-impact-tool-v1.0.0 - Owner: https://github.com/ajtazer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0f8300ded775c4f990f984dab0c89e7d46de4cae -
Trigger Event:
push
-
Statement type: