Icex0/firebase-pentest-checklist
GitHub: Icex0/firebase-pentest-checklist
这是一份详尽的 Firebase 渗透测试检查清单,涵盖了 Auth、数据库及存储等核心服务的漏洞检测点、报告判定标准及配套的 OpenFirebase 自动化指令。
Stars: 1 | Forks: 0
# Firebase 渗透测试清单
一份用于测试 Firebase 服务的实用清单。每个章节末尾都附有相关的 [OpenFirebase](https://github.com/Icex0/OpenFirebase) 命令,当某个领域超出该工具范围且必须手动测试时会特别标注。
**发现标准** 在每个章节的 **报告时机** 下说明。如果不满足任何这些条件,则不构成漏洞 —— Firebase 故意公开了许多端点,且服务根路径返回 `200` 本身并不代表配置错误。
## 配套工具
本清单是工具无关的,但有两个开源项目可以自动化执行下面的大部分检查:
- **[OpenFirebase](https://github.com/Icex0/OpenFirebase)** — Firebase 侦察和安全扫描器。从 APK/IPA 中提取配置,扫描 RTDB / Firestore / Storage / Remote Config(未认证 + 已认证),支持写入检查以及扫描硬编码的服务账号/私钥。下面大多数章节都包含相应的 `openfirebase` 命令。
- **[FireSA](https://github.com/Icex0/FireSA)** — 服务账号后渗透利用。在恢复 Firebase Admin SDK 私钥后(参见 §10)使用,以枚举 IAM 权限并进行横向移动。
## 1. 如何使用此清单
- 项目按 Firebase 服务分组。
- 复选框 (`- [ ]`) 用于跟踪针对每个目标的进度。
- “报告时机” 描述了有效发现所需达到的最低标准。
## 2. 侦察与发现
- [ ] 识别 Firebase 使用情况并提取客户端配置。字段相同,但不同平台命名不同:
- **Android** — Gradle 插件在构建时将 `google-services.json` 烘焙进 `res/values/strings.xml`(或 `secrets.xml`)中。原始 JSON **不**在 APK 中。查找 `google_api_key`, `google_app_id`, `firebase_database_url`, `project_id`, `google_storage_bucket`, `gcm_defaultSenderId`, `default_web_client_id`。OpenFirebase 可通过 `openfirebase -f app.apk`(或针对目录快速模式使用 `-d ./apks -F`)自动完成此操作。
- **iOS** — `GoogleService-Info.plist` 原样打包在 `.ipa` 内部。字段包括:`API_KEY`, `PROJECT_ID`, `DATABASE_URL`, `STORAGE_BUCKET`, `GOOGLE_APP_ID`, `GCM_SENDER_ID`。
- **Web** — JS 包包含一个 `firebaseConfig` 对象,其中含有 `apiKey`, `authDomain`, `projectId`, `databaseURL`, `storageBucket`, `appId`, `messagingSenderId`。
- **网络** — 流量指向 `*.cloudfunctions.net` 或 `*.run.app` 表明使用了 Cloud Functions for Firebase。
- [ ] 枚举同级/暂存项目 ID(例如 `-dev`, `-staging`, `-test`, `-prod`)
- [ ] 确定每个项目启用了哪些服务(RTDB, Firestore, Storage, Remote Config, Auth, Functions, Hosting)
**OpenFirebase**
```
# 从单个 APK 中提取
openfirebase -f app.apk
# 从 APK 目录中提取(快速模式,仅限 strings.xml)
openfirebase -d ./apks -F
```
## 3. 身份验证 (Identity Platform / Firebase Auth)
Firebase Auth 通过位于 `identitytoolkit.googleapis.com` 的 Identity Toolkit API 暴露。客户端中的 API key 本身**不是**机密信息 — Google 在文档中明确说明了这一点([API keys for Firebase](https://firebase.google.com/docs/projects/api-keys))。只有当它与不安全的规则结合,或启用了不应开放的提供商时,才构成发现。
- [ ] 是否启用了匿名登录?
- [ ] 检查是否允许电子邮件/密码注册以请求后续步骤的 bearer token
POST /v1/accounts:signUp?key=API_KEY
{"email":"test@example.com","password":"Test1234!","returnSecureToken":true}
- [ ] 通过 `accounts:createAuthUri` 进行电子邮件枚举(返回 `registered: true/false`)
POST /v1/accounts:createAuthUri?key=API_KEY
{"identifier":"victim@example.com","continueUri":"http://localhost"}
此行为是可配置的;当启用 **电子邮件枚举保护** 时,响应是统一的(没有 `registered` / `signinMethods` 字段)。当保护 **禁用** 时,响应会泄露 `"registered": true|false` 和 `"signinMethods": [...]` — 这 **是** 一个发现,因为它允许攻击者确认任意电子邮件地址是否为该应用的用户。参见 [Email enumeration protection](https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection)。
示例 — 保护 **禁用**(发现):
{
"kind": "identitytoolkit#CreateAuthUriResponse",
"allProviders": ["password"],
"registered": true,
"sessionId": "...",
"signinMethods": ["password"]
}
示例 — 保护 **启用**(统一,不是发现):
{
"kind": "identitytoolkit#CreateAuthUriResponse",
"sessionId": "..."
}
- [ ] Token 可在同一项目中重用于其他 Firebase 服务
- [ ] 是否启用了自助账户删除?(Identity Platform:*User account management → User actions → Enable delete*)
POST /v1/accounts:delete?key=API_KEY
{"idToken":""}
`200 {}` 响应表示已登录用户的账户已被删除。当开关处于 **关闭** 状态时,API 返回 `ADMIN_ONLY_OPERATION`。在传统的 Firebase Auth 项目中(未升级 Identity Platform),该开关不存在,且始终允许自助删除;在那阻止它的唯一方法是使用 Identity Platform [blocking function](https://cloud.google.com/identity-platform/docs/blocking-functions)。参见 [REST: delete account](https://firebase.google.com/docs/reference/rest/auth#section-delete-account)。
**OpenFirebase**
当 `--check-with-auth` 成功(注册或登录)时,OpenFirebase 会自动针对刚认证的电子邮件测试 `accounts:createAuthUri`,如果响应泄露了 `registered` / `signinMethods`,则打印 `[FINDING] Email enumeration protection is DISABLED ...`。
OpenFirebase 仅执行 **电子邮件/密码** 注册和 **匿名** 认证。其他身份提供商(Google, Apple, Facebook, GitHub, Microsoft, SAML, OIDC, phone)**不会**被自动测试 — 如果目标依赖于这些,请通过 `accounts:createAuthUri` 枚举启用的提供商并手动测试每一个。
```
# 尝试电子邮件/密码注册,回退到匿名,然后使用获取的 token 重试失败的读/写检查
openfirebase --project-id PROJECT_ID --read-all --check-with-auth \
--email pentester@example.com --password 'SecurePass123!' \
--api-key AIza...
```
API key 可能会应用限制(如果你尝试注册但它受限,详细响应会告诉你)。这些限制由服务器端通过 header / IP 匹配强制执行,没有加密绑定,因此所有客户端限制都可以被欺骗:
| 限制类型 | OpenFirebase 标志 |
|---|---|
| Android 应用 | `--cert-sha1 --package-name com.example.app` |
| iOS 应用 | `--ios-bundle-id com.example.app` |
| HTTP referrer | `--referer https://app.example.com/` |
| IP 地址 | **无法从外部绕过** — 需要源 IP 控制(例如范围内的 SSRF 或受控主机) |
**报告时机:**
- 启用了匿名或开放的电子邮件/密码注册,**且**该 token 解锁了 RTDB、Firestore、Storage 或 Functions 中应受限制的数据/操作。
- 项目上 **禁用** 了电子邮件枚举保护(`accounts:createAuthUri` 返回 `registered` / `signinMethods`)。这本身就是一个发现 — 攻击者可以验证任意电子邮件是否为应用用户。
- 仅启用匿名认证且没有下游影响,属于信息收集。
- 应用没有供用户删除自己账户的 UI,但 `accounts:delete` 仍能通过用户 ID token 成功。**Enable delete** 开关应处于关闭状态;保持开启与产品意图相悖,并允许拥有被盗 token / XSS / 钓鱼原语的攻击者销毁受害者账户。严重程度取决于删除是否可逆以及是否会级联导致规则依赖的孤立数据。
## 4. Realtime Database (RTDB)
RTDB 安全性由 [Realtime Database Rules](https://firebase.google.com/docs/database/security) 管理。任何路径都可以通过附加 `.json` 进行查询。
- [ ] 数据库根路径的未认证读取
https://PROJECT_ID.firebaseio.com/.json
https://PROJECT_ID-default-rtdb.firebaseio.com/.json
https://PROJECT_ID-default-rtdb.europe-west1.firebasedatabase.app/.json
状态解释:
- 带有 JSON body 的 `200` → 公开读取
- 带有 `null` 的 `200` → 公开但根为空(仍然是公开的;检查已知路径)
- `401` → 规则要求认证(非公开)
- `404` -> 此名称下没有数据库
- `423` -> 数据库已停用
- [ ] 未认证写入(POST 会创建一个新的 push-ID 子项,不会覆盖现有数据)
POST /openfirebase-unauth-check.json HTTP/1.1
Host: PROJECT_ID.firebaseio.com
Content-Type: application/json
{"unauth_access":"OpenFirebase_write_check"}
包含 `{"name":"-N..."}` 的 `200` 响应确认写入成功 — 重新读取同一路径以验证。
- [ ] 顶级键的浅层列表
/.json?shallow=true
- [ ] 使用 §3 中的 token 进行认证读/写 — 重复上述根路径和浅层 GET 以及 POST 操作,但附加 `?auth=`。然后创建第二个账户,尝试读/写属于第一个账户的路径(用户 2 读取 `/users/.json`)。常见规则错误:`.read: auth != null` 将所有内容暴露给任何登录用户。
- [ ] 同一项目中的辅助数据库。Firebase 允许每个项目有多个 RTDB 实例;第二个实例默认使用 **项目 ID** 作为其名称(没有 `-default-rtdb` 后缀)。尝试:
https://PROJECT_ID.firebaseio.com/.json
https://PROJECT_ID.europe-west1.firebasedatabase.app/.json
**OpenFirebase**
```
openfirebase --project-id PROJECT_ID --read-rtdb \
--write-rtdb ./openfirebase/payloads/openfirebase.json
```
**报告时机:**
- 未认证读取返回任何非空数据,**或**
- 未认证/匿名写入成功(通过读回写入的键验证),**或**
- 认证用户可以读/写属于其他用户的路径(`auth.uid` 作用域失效)。
## 5. Cloud Firestore
Firestore 由 [Cloud Firestore Security Rules](https://firebase.google.com/docs/firestore/security/get-started) 管理。与 RTDB 不同,Firestore 规则 **不是分层** 的 — 除非明确写入,否则 `/users/{id}` 上的规则不保护 `/users/{id}/private/{doc}`。
- [ ] 未认证列出已知集合
GET https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases/(default)/documents/COLLECTION
- 带有 `documents` 的 `200` → 公开读取
- `200` 空 `{}` → 数据库是公开的但集合为空/不存在!模糊测试常见集合!
- `403` → 规则拒绝
- `404` → 此项目中没有 Firestore 数据库
- [ ] 针对任何返回 `200` 的项目模糊测试常见集合名称
- [ ] 写入测试文档
POST /v1/projects/PROJECT_ID/databases/(default)/documents/firestore_unauthenticated_access
{"fields":{"title":{"stringValue":"unauth_write_check"}}}
- [ ] 子集合遍历(例如 `users/{uid}/private`)— 常见的规则绕过
- [ ] 使用 §3 中的 token 进行认证读/写 — 你能读取其他用户的文档吗?
- [ ] 命名(非默认)数据库 — Firestore 现在每个项目支持多个数据库([文档](https://firebase.google.com/docs/firestore/manage-databases))
**OpenFirebase**
```
openfirebase --project-id PROJECT_ID \
--read-firestore --write-firestore "unauth_write_check" \
--fuzz-collections ./openfirebase/wordlist/firestore-collections.txt
```
**报告时机:**
- 特定集合或文档未经认证返回数据,**或**
- 未经认证/匿名写入集合成功,**或**
- 认证用户读/写属于另一个用户的文档。
OpenFirebase 仅扫描 `(default)` 数据库 — 命名数据库必须手动测试。
## 6. Cloud Storage for Firebase
Storage 由 [Storage Security Rules](https://firebase.google.com/docs/storage/security) 管理。Firebase Storage REST API 和底层 GCS bucket 是不同的攻击面。
- [ ] 通过 Firebase Storage API 列出 bucket
https://firebasestorage.googleapis.com/v0/b/PROJECT_ID.appspot.com/o
https://firebasestorage.googleapis.com/v0/b/PROJECT_ID.firebasestorage.app/o
- 带有 `items` 的 `200` → 允许列出
- `400` → rules v1,不允许列出(单个对象读取可能仍有效)
- `403` → 权限被拒绝
- `412` → 缺少服务账号权限
- [ ] 未经认证读取已知对象名称。即使列出被拒绝(rules v1 返回 `400`,rules v2 可能拒绝 `list` 但允许 `get`),单个对象仍可能是公开的。从 APK 字符串、JS 包、泄露的 URL 或可猜测模式(`avatars/.jpg`, `invoices/.pdf`, `backups/db.sql`)中获取对象名称。路径必须经过 URL 编码(`/` → `%2F`):
GET /v0/b/PROJECT_ID.appspot.com/o/avatars%2F123.jpg?alt=media HTTP/1.1
Host: firebasestorage.googleapis.com
`?alt=media` 返回文件字节;省略它以获取元数据 JSON。
- [ ] 未经认证上传测试文件
POST /v0/b/PROJECT_ID.appspot.com/o?name=openfirebase_write_check.txt HTTP/1.1Host: firebasestorage.googleapis.com
Content-Type: text/plain
OpenFirebase - Unauth Firebase write access found
带有描述上传对象的 JSON body 的 `200` 响应确认写入。重新获取对象以验证。
- [ ] 使用 §3 中的 token 重复上传(`Authorization: Bearer `),并检查认证用户是否可以写入应受限制的路径(例如 `/users//...`)。
- [ ] 底层 Google Cloud Storage bucket — 相同数据,不同访问系统。Firebase Storage Rules 管理 `firebasestorage.googleapis.com`;**GCS IAM** 管理 `storage.googleapis.com`。一个 bucket 可以在一个上锁定而在另一个上公开(例如在 GCP IAM 中直接向 `allUsers` 授予 `roles/storage.objectViewer`)。探测两个端点:
GET /storage/v1/b/PROJECT_ID.appspot.com/o HTTP/1.1
Host: storage.googleapis.com
GET /PROJECT_ID.appspot.com/path/to/object.pdf HTTP/1.1
Host: storage.googleapis.com
任一端点返回 `200` 都是发现(反之亦然:仅在 `firebasestorage.googleapis.com` 上返回 `200` 意味着 Firebase 规则宽松但 IAM 正常)。OpenFirebase 会在 `--read-storage` / `--write-storage` 下自动测试这两个攻击面。
**OpenFirebase**
```
openfirebase --project-id PROJECT_ID \
--read-storage \
--write-storage ./openfirebase/payloads/openfirebase_storage_write_check.txt
```
**报告时机:**
- Bucket 列表返回了本意不公开的对象名称,**或**
- 未认证读取返回了敏感对象,**或**
- 未认证/匿名上传成功(通过重新读取对象验证)。
故意公开的资源 bucket(例如应用图标、营销媒体)的 `200` 列表不是发现!
## 7. Remote Config
Remote Config 从以下位置获取:
```
POST https://firebaseremoteconfig.googleapis.com/v1/projects/PROJECT_ID/namespaces/firebase:fetch?key=API_KEY
```
此端点设计为由客户端调用,因此预期返回 `200`。发现点在于 **响应包含的内容**。
- [ ] 使用提取的 API key + App ID 获取 Remote Config
- [ ] 审查参数以查找:API 密钥、机密信息、内部 URL、揭示未发布功能的特性标志、调试开关、JWT 签名材料。使用 Betterleaks 和 Trufflehog 扫描远程配置。
- [ ] 使用提取的 SHA-1 + 包名绕过 Android API key 限制(`X-Android-Package`, `X-Android-Cert` headers)
**OpenFirebase**
```
openfirebase --project-id PROJECT_ID --read-config \
--api-key AIza... --app-id 1:...:android:... \
--cert-sha1 --package-name com.example.app
```
**报告时机:**
- Remote Config 暴露了机密、凭据、内部主机名或未发布的特性标志。
- 仅仅能够获取 Remote Config **不是** 发现!
## 8. Cloud Functions for Firebase (WIP)
通过 Firebase 部署的 Cloud Functions 会落在以下地址之一:
```
https://-.cloudfunctions.net/ # 1st gen
https://--.a.run.app # 2nd gen (Cloud Run)
```
- [ ] 从 JS 包、移动反编译和 `firebase.json` 重写规则中枚举函数名称
- [ ] 未经认证探测 HTTPS 函数
- [ ] Callable 函数:POST 请求发送到函数 URL,body 为 `{"data": {...}}`,header 为 `Content-Type: application/json`。可以添加来自 §3 的匿名 `idToken` 作为 `Authorization: Bearer `。
- [ ] 检查 IAM:第二代函数是 Cloud Run 服务,可能设置为 `allUsers` 调用者
- [ ] 对每个端点进行标准 Web 测试:IDOR、SSRF、注入、批量赋值
- [ ] [App Check](https://firebase.google.com/docs/app-check) 强制执行 — 函数是否拒绝没有有效 App Check token 的请求?
**报告时机:**
- 未经认证的调用执行了特权操作或返回了调用者不应看到的数据,**或**
- 在函数逻辑中发现标准 Web 漏洞(IDOR/SSRF/注入等),**或**
- 声称强制执行 App Check 但可以通过省略 header 绕过。
## 9. Firebase Hosting (WIP)
- [ ] 检查暴露的 `firebase.json` 并审查 `rewrites`、`headers`、`redirects`
- [ ] 生产环境中提供的源映射(`*.js.map`)
- [ ] 泄露未发布功能的预览频道(`https://PROJECT_ID---.web.app`)
- [ ] 代理到 Cloud Functions / Cloud Run 的重写规则 — 像第 8 节一样测试重写路径
**报告时机:** 托管配置错误泄露了源代码、机密,或暴露了不应公开的函数/路由。
## 10. Service Accounts and IAM
服务账号是应用程序用于以编程方式向 Firebase 进行身份验证的非人类 Google/Firebase 身份,它使用私钥 JSON 文件而不是密码。一个项目可以有多个服务账号,每个账号拥有不同的 IAM 角色和权限范围。
如果在 APK/IPA、公共仓库或 JS 包中发现服务账号私钥 — 无论是作为原始 JSON blob(`"type": "service_account"`)还是作为硬编码的单个字段(`-----BEGIN RSA PRIVATE KEY-----` 伴随着 `iam.gserviceaccount.com` 电子邮件)— 其影响取决于该账号被授予的角色。它不必是 Admin SDK 服务账号即可构成有效发现。也就是说,如果它 **是** Admin SDK 账号(`firebase-adminsdk-xxxxx@PROJECT_ID`),它将绕过所有安全规则并赋予对所有 Firebase 服务的广泛读/写访问权限。
- [ ] 确定实际范围 — 使用 FireSA `--check-permissions`(见下文)
- [ ] 确认对 RTDB、Firestore、Storage 和 Auth 的影响(列出/删除/创建用户、数据库、存储文件等)
**OpenFirebase**
```
# 在 APK 提取期间自动找到;也可以手动提供:
openfirebase --project-id PROJECT_ID \
--service-account firebase-adminsdk-xxxxx@PROJECT_ID.iam.gserviceaccount.com \
--private-key ./key.pem --read-all
```
通过服务账号认证的结果在 OpenFirebase 输出中标记为 `PUBLIC_SA`。
要获取 IAM 权限清单,请使用 [FireSA](https://github.com/Icex0/FireSA):
```
firesa --service-account firebase-adminsdk-xxxxx@PROJECT_ID.iam.gserviceaccount.com \
--private-key ./key.pem --check-permissions
```
FireSA 还可以直接使用 `--list-all`、`--list-users`、`--list-iam` 等标志枚举用户、RTDB、Firestore、Storage 和 IAM,并支持用户创建/更新/删除以演示影响。
**报告时机:** 密钥成功认证并授予超出普通用户权限的任何访问权限。这几乎总是 **严重** 级别。
## 12. OpenFirebase 命令快速参考
[OpenFirebase](https://github.com/Icex0/OpenFirebase) 的标志。完整选项列表请参阅项目 README。
| 章节 | 命令标志 |
|---|---|
| 从 APK/IPA 提取 | `-f`, `-d` |
| RTDB 读/写 | `--read-rtdb`, `--write-rtdb` |
| Firestore 读/写 | `--read-firestore`, `--write-firestore`, `--fuzz-collections` |
| Storage 读/写 | `--read-storage`, `--write-storage` |
| Remote Config | `--read-config` |
| 所有读 / 所有写 | `--read-all`, `--write-all` |
| 认证重试 | `--check-with-auth`, `--email`, `--password` |
| Service account | `--service-account`, `--private-key` |
| 从之前的提取恢复 | `--resume`, `--resume-auth-file` |
| 通过 Burp 代理 | `--proxy http://127.0.0.1:8080` |
完整未认证 + 认证扫描:
```
openfirebase -d ./apks --read-all --write-all \
--write-storage ./openfirebase/payloads/openfirebase_storage_write_check.txt \
--write-rtdb ./openfirebase/payloads/openfirebase.json \
--write-firestore "unauth_write_check" \
--fuzz-collections ./openfirebase/wordlist/firestore-collections.txt \
--check-with-auth --email pentester@example.com --password 'SecurePass123!'
```
## 13. 参考
- [Firebase Security Rules overview](https://firebase.google.com/docs/rules)
- [Realtime Database Rules](https://firebase.google.com/docs/database/security)
- [Cloud Firestore Security Rules](https://firebase.google.com/docs/firestore/security/get-started)
- [Cloud Storage Security Rules](https://firebase.google.com/docs/storage/security)
- [API keys for Firebase](https://firebase.google.com/docs/projects/api-keys)
- [Firebase App Check](https://firebase.google.com/docs/app-check)
- [OpenFirebase](https://github.com/Icex0/OpenFirebase) — Firebase recon and security scanner
- [FireSA](https://github.com/Icex0/FireSA) — Firebase service-account post-exploitation
标签:API安全, Auth, Firebase, FireSA, Firestore, Google Cloud, IAM, JSON输出, OpenFirebase, Realtime Database, reconnaissance, Remote Config, 安全检查表, 安全测试, 安全清单, 攻击性安全, 未授权访问, 权限管理, 模型越狱, 目录枚举, 移动安全, 防御加固