Vulnerabilities
firebase.json vs package.json on Production Origins
November 30, 2023
firebase.json vs package.json on production origins is two project files that must not sit next to index.html. /package.json donates npm names and versions. /firebase.json donates Firebase Hosting rewrites, redirects, headers, ignore globs, and sometimes Cloud Function names — a map of how the site is wired. Neither is a pentest. A private repo may keep both. The marketing CDN must not serve the config as a static object. RoastMyOpsec probes /package.json with a bounded GET. It does not currently score /firebase.json, does not parse Hosting rules, and does not call Cloud Functions.
The practical difference
package.json is Node inventory. firebase.json is how Hosting routes, caches, and attaches headers. Dockerfile is how the image is built. .env is secrets. A 200 on /firebase.json is an information leak even when every rewrite looks boring. Deny the name at the edge.
Firebase Hosting still applies the config you deploy. The miss is leaving a copy of that JSON as a downloadable file in public/.
How to choose what to publish
CI: fail if firebase.json, .firebaserc, package.json, or lockfiles appear in a static marketing artifact that is not the Hosting deploy itself — the live site should not expose the file at a guessable URL. CDN: deny /firebase.json. Keep the config in the private repo. Staging hostnames that are guessable get the same deny list.
| File | Typical leak | Roast today | Takeaway |
|---|---|---|---|
| /package.json | npm names and versions | Bounded GET | See public package.json vs OSV |
| /firebase.json | Rewrites, headers, functions | Not scored; deny anyway | Same class |
| /.firebaserc | Project aliases | Not scored | Deny the name |
| /.env | Live secrets | Bounded signature GET | See .git vs .env |
When firebase.json still wins (off the public URL)
It wins in a private repo and in the Firebase CLI deploy. It never wins as a downloadable object next to index.html. Pair with Dockerfile vs package.json if the same zip also shipped a container recipe.
What the roast can prove
A reachable /package.json can surface. firebase.json is not a scored path. Confirm a 404 yourself. Pair with robots.txt Disallow if someone thought hiding the name was access control.
Common mistakes
The first mistake is copying the whole Firebase project folder into public/ so Hosting also served firebase.json.
The second mistake is putting API keys or internal function URLs in a public firebase.json.
The third mistake is Disallow: /firebase.json and calling it access control.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Is a public firebase.json a vulnerability?
- It is an information leak. Remove it from the public tree and deny the name. It is not always a credential dump, but it is not harmless.
- Does RoastMyOpsec fetch firebase.json?
- Not as a scored path today. It does probe /package.json. Deny Firebase config filenames at the edge anyway.
- Does Firebase need firebase.json on the live origin?
- No. The CLI deploys the config. Visitors do not need to download it.
Sources
Related guides
Vulnerabilities
Public package.json vs Lockfile Advisories on ProductionVulnerabilities
Dockerfile vs package.json on Production OriginsVulnerabilities
go.mod vs package.json on Production Origins