Service:
Firebase Authentication Emulator (firebase-tools)local dev toolscustom web appsProtocol:
TCPPort:
9099Used for:
Running the Firebase Local Emulator Suite's Authentication emulator for local development and testing, plus assorted dev tools and custom web apps that bind to this non-standard portPort 9099 is the default listen port for the Authentication emulator in the Firebase Local Emulator Suite — the fake auth backend that firebase emulators:start spins up so developers can test sign-up, login, and token flows without touching real Firebase. It is meant to run on 127.0.0.1 and talk only to your app during development. That is the whole story of this port: it is a local dev tool, not a production service, and the Firebase emulators deliberately ship with no security rules and no real authentication because they exist to be poked at freely from your own machine. The danger is not a protocol bug — it is a developer accidentally exposing the emulator to the network. Bind it to 0.0.0.0, forward it through a tunnel, or leave it up on a shared dev box, and anyone who can reach 9099 gets an auth server with the safety catches removed. Port 9099 also gets squatted by other dev tools and custom web apps, so the first job on an open 9099 is to confirm whether an emulator or some other HTTP listener is answering.
Why It’s Open
The overwhelmingly common reason port 9099 is open is that someone ran the Firebase Local Emulator Suite. When you start the emulators, the Authentication emulator binds 9099 by default (Firestore, Realtime Database, Functions, and the Emulator UI take their own ports), and it stays up as long as the dev session runs. On a laptop that’s exactly as intended. The problem starts when the emulator ends up reachable from beyond localhost:
- A
hostoverride infirebase.json. Setting the emulator’shostto0.0.0.0(a common “let my phone/teammate hit it” hack) exposes 9099 to the whole LAN or, on a cloud VM, the internet. - A shared or cloud dev box. Running the emulators on a jump host, CI runner, or cloud workstation that has a public IP or a permissive security group.
- Tunnels and port-forwards. ngrok, SSH
-L/-R, VS Code port forwarding, or a Docker-p 9099:9099mapping that quietly publishes the emulator.
Beyond Firebase, 9099 is unassigned by IANA, so it’s a convenient pick for custom dashboards, internal web APIs, reverse proxies, IoT control panels, and microservices that each want their own port during testing or staging. Because nothing “important” is supposed to live here, an open 9099 is easy to forget about and leave running long after the work that started it is done.
Common Risks
- Exposed Firebase Auth emulator — the headline risk. The emulator has no security rules and no genuine authentication by design. Reach it and you can create, list, and delete user accounts at will, mint tokens for any user, and drive the fake auth state however you like. It is a wide-open identity backend, and everything it does is unauthenticated.
- Out-of-band code disclosure. The emulator exposes an
/emulator/v1/projects/{project}/oobCodesendpoint that returns the email-verification and password-reset links it has generated. Anyone who can read these can complete account-takeover flows against the test environment — and against anything a careless developer wired to it. - Unsigned tokens that fool other emulators. The Auth emulator issues unsigned ID tokens that the Firebase Admin SDK and the other emulators accept when
FIREBASE_AUTH_EMULATOR_HOSTis set. If that variable ever leaks into a shared or staging environment, forged identities flow straight through the trust chain. - Unauthenticated dev tools and dashboards. A non-Firebase service squatting on 9099 (an internal dashboard, admin panel, or API) frequently ships with no login at all, exposing sensitive functions directly.
- Debug/test servers left running. Dev servers on this port often run in debug mode with verbose stack traces, source maps, or elevated privileges — a rich information-disclosure and pivot surface.
- No encryption. The emulator and most dev listeners speak plaintext HTTP, so anything sent over an untrusted network can be sniffed or tampered with.
Want to save time on reporting?
Let PentestPad generate, track, and export your reports - automatically.

Enumeration & Testing
The goal on port 9099 is to confirm what is listening — a Firebase emulator, some other dev HTTP service, or nothing you can account for — and then, if it’s the emulator, prove it’s exposed.
Detect the service and version
nmap -sV -p 9099 <target>Grab the HTTP banner
curl -i http://<target>:9099/The Authentication emulator answers HTTP and its responses look like Google’s Identity Toolkit API (the same shape as identitytoolkit.googleapis.com), returning JSON rather than a normal web page. A JSON body, identitytoolkit/securetoken error shapes, or emulator-flavoured fields are the tell that you’re talking to a Firebase Auth emulator and not a random web app.
Confirm it’s the emulator and pull emulator-only endpoints
# List the accounts the emulator is holding (unauthenticated)curl -s "http://<target>:9099/emulator/v1/projects/<project-id>/accounts"
# Read generated out-of-band codes: email-verification and PASSWORD-RESET linkscurl -s "http://<target>:9099/emulator/v1/projects/<project-id>/oobCodes"
# Emulator configurationcurl -s "http://<target>:9099/emulator/v1/projects/<project-id>/config"These /emulator/v1/... paths only exist on the emulator, never on production Firebase. If they answer without credentials, the emulator is exposed and its auth state is yours to read and rewrite. Even without a known project-id, the root banner and error responses are enough to fingerprint the service.
Fingerprint anything else on 9099
whatweb http://<target>:9099/nikto -h http://<target>:9099/If it isn’t a Firebase emulator, whatweb/nikto and the response headers (Server, X-Powered-By, framework cookies, login pages) identify the actual stack — a Node/Express dashboard, a proxy, an IoT panel — which you then test as that specific application.
Record every open port 9099, the service you positively identified, and any account or oobCode you can read without auth, so the evidence lands in the pentest report instead of a scratch terminal you’ll lose.
What to Look For
| Checkpoint | What it means |
|---|---|
| Port 9099 reachable from outside localhost | A dev-only emulator or tool is exposed beyond its intended 127.0.0.1 audience |
JSON / identitytoolkit-style response on / |
Firebase Authentication emulator confirmed |
/emulator/v1/projects/.../accounts answers unauthenticated |
Full read/write over the fake user store — create, list, delete accounts, mint tokens |
/emulator/v1/projects/.../oobCodes returns links |
Password-reset / email-verification codes leak — account-takeover flows |
FIREBASE_AUTH_EMULATOR_HOST set in a non-dev environment |
Admin SDK will trust unsigned emulator tokens — forged identities |
| Non-Firebase login page or dashboard on 9099 | A custom/dev app exposed, often with no authentication |
| Plaintext HTTP, debug output, stack traces | Test environment left accessible; information disclosure |
Known CVEs and Exploits
There is no CVE for “port 9099,” and no network CVE for the Firebase Authentication emulator itself. This is by design, not oversight: the emulator is a local development tool that intentionally ships without security rules and without real authentication, so its “vulnerability” is simply being reachable. The only meaningful risk here is a misconfiguration/exposure one — a dev-only service bound where the network can see it — which no patch fixes and no CVE tracks.
- Firebase Local Emulator Suite guidance (not a CVE) — Google’s own documentation states the emulators do not replicate IAM or enforce production access controls, that the Auth emulator issues unsigned tokens, and that
FIREBASE_AUTH_EMULATOR_HOSTmust never be set in production. The emulators are meant for127.0.0.1; the fix for an exposed 9099 is to unbind it, not to patch it.
Corrections to the previous version of this page. The old stub cited two “CVEs/exploits” that do not belong to port 9099 or to any Firebase service, and both have been removed:
- CVE-2019-5413 was labelled “Express template injection.” Verified on NVD it is actually a command-injection flaw in the npm package
morgan(< 1.9.1) via theformatparameter — unrelated to this port or the Firebase emulator.- Exploit-DB 47837 was labelled “Python http.server RCE.” It is actually the Nostromo
nhttpd1.9.6 remote code execution exploit (CVE-2019-16278) — a completely different web server, nothing to do with 9099.If a real, non-emulator service (an Express/Node dashboard, a proxy, etc.) turns out to be listening on 9099, look up the CVEs for that product and version — not for “port 9099.”
Mitigation
- Bind emulators to localhost. Leave the Firebase emulators on
127.0.0.1(the default). Never set the emulatorhostto0.0.0.0infirebase.jsonon any machine the network can reach. - Never expose the emulator to untrusted networks. No public IPs, no permissive cloud security groups, no ngrok/SSH/Docker port publishing for 9099. If a teammate genuinely needs it, use a private VPN or an SSH tunnel scoped to them, not an open port.
- Keep
FIREBASE_AUTH_EMULATOR_HOSTout of staging and production. It must only ever be set in local dev shells; if it leaks elsewhere the Admin SDK will accept forged, unsigned emulator tokens. - Don’t run emulators on shared or long-lived boxes. Treat them as ephemeral local processes; shut them down when the dev session ends rather than leaving 9099 up for weeks.
- For non-emulator apps on 9099: add real authentication and access controls, bind to localhost or put the service behind a reverse proxy with TLS on 443, and disable debug/verbose errors on anything the network can reach.
- Firewall and audit port 9099. Block it at the perimeter, and periodically scan dev and cloud environments for forgotten services on non-standard ports like 9099, 9000, 8080, 8000, and 3000.
Real-World Example
The canonical port-9099 incident isn’t an exploit against a bug — it’s a developer convenience that turns into an exposure. A team wants to demo their app to a colleague or test it from a phone, so someone sets the Firebase emulators’ host to 0.0.0.0 in firebase.json, or runs firebase emulators:start on a cloud dev VM and opens the port in the security group “just for testing.” Now the Authentication emulator on 9099 is reachable from the internet, and because emulators enforce no security rules and no authentication, anyone who scans the host can curl /emulator/v1/projects/<project>/accounts to enumerate every test user, hit /oobCodes to harvest password-reset links, and create accounts or mint unsigned tokens at will. If any downstream service still trusts FIREBASE_AUTH_EMULATOR_HOST, those forged identities flow onward. Nothing was “hacked” in the classic sense — a tool built to be wide open on localhost was simply placed where the whole network could see it. That is the entire risk model of port 9099.
FAQ
What is port 9099 used for?
Port 9099 is the default port for the Authentication emulator in the Firebase Local Emulator Suite — the fake auth backend that firebase emulators:start runs so developers can test sign-up and login flows locally without touching real Firebase. It’s meant to listen on 127.0.0.1. The same port is also picked by assorted dev tools, custom web APIs, dashboards, and microservices because it’s unassigned by IANA.
Why is port 9099 open on my machine?
Almost always because you (or a dependency’s dev script) started the Firebase emulators. That’s normal and safe as long as it’s bound to localhost. It becomes a problem only if the emulator is exposed to the network — via a 0.0.0.0 host setting, a cloud VM with a public IP, or a tunnel/port-forward. If you don’t recognise the service, fingerprint it with curl -i http://localhost:9099/ before trusting it.
Is the Firebase Auth emulator dangerous to expose?
Yes. The emulators deliberately ship with no security rules and no real authentication — they exist to be poked at freely from your own machine. Exposed to the network, the Auth emulator lets anyone list, create, and delete accounts, read generated password-reset links, and mint tokens. It should never be reachable beyond localhost or a tightly scoped private tunnel.
Is there a CVE for port 9099 or the Firebase emulator?
No. There’s no CVE for the port and no network CVE for the Auth emulator itself — the risk is a design/misconfiguration one (a local-only tool left reachable), which no patch addresses. Two CVE-style entries on the old version of this page (CVE-2019-5413 and Exploit-DB 47837) were mislabeled and belonged to unrelated software; they’ve been removed.
How do I secure or close port 9099?
Keep the emulators bound to 127.0.0.1 (never 0.0.0.0), don’t run them on public-facing or shared hosts, keep FIREBASE_AUTH_EMULATOR_HOST out of any non-dev environment, and firewall 9099 at the perimeter. For a non-Firebase app on 9099, add authentication, put it behind a reverse proxy with TLS, and disable debug output. Shut the emulator down when you’re done and rescan to confirm the port is closed.
TL;DR
- Service: Firebase Authentication emulator (Firebase Local Emulator Suite, default 9099) — plus miscellaneous dev tools and custom web apps
- Default port: 9099/TCP (localhost by design;
firebase emulators:start) - Biggest risk: an exposed emulator — it has no security rules and no real auth, so anyone who reaches it can read/create/delete accounts, harvest password-reset links, and mint tokens. No port-specific CVE; the risk is misconfiguration, not a bug
- Mitigation: keep emulators on
127.0.0.1, never bind0.0.0.0or tunnel the port, keepFIREBASE_AUTH_EMULATOR_HOSTout of prod/staging, firewall 9099, and fingerprint any non-emulator listener and secure it as its own app