FixVibe

// docs / baas security / firebase if-true explainer

Firebase allow read, write: if true 解析:它做什麼以及如何修復

<code>allow read, write: if true;</code> 是生產中最常見的單一 Firebase 設定錯誤。它是建立新資料庫時 Firebase 主控台所建議的測試模式預設值、AI 編碼工具從文件再生的規則,以及向網際網路上任何人開放整個 Firestore 資料庫的規則。本文精確解釋語法、展示此規則生效時攻擊者看到什麼,並提供四個適合不同使用情境、逐步更嚴格的替代方案。

逐行語法解析

一份完整的 Firestore 測試模式規則文件是六行:

firebase
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

解析:

  • rules_version = '2'; 選擇 v2 規則引擎 (目前)。較舊的 v1 規則已棄用。
  • service cloud.firestore 將區塊限定到 Firestore。Realtime Database 使用不同的 JSON 為基礎的語法;Cloud Storage 使用 service firebase.storage
  • match /databases/{database}/documents 繫結特殊的 (default) 資料庫 (大多數專案只有一個)。
  • match /{document=**} 是遞迴萬用字元。** 比對任意深度的任意路徑。與 {document} 結合,這會擷取每個集合中的每個文件 — 單一 match 子句統治整個資料庫。
  • allow read, write: if true; 是規則主體。readwrite 都被允許;條件 if true,嗯,永遠為真。read 涵蓋 getlist 操作;write 涵蓋 createupdatedelete

淨效果:任何持有 Firebase 專案 ID 並擁有正確 SDK 的用戶端,皆可讀取或寫入任何集合中的任何文件。不需要驗證。不強制速率限制。

Firebase 為何將此作為預設值

Firebase 希望你在建立專案後的前 30 秒內就能開始寫程式。替代方案 — 在任何讀寫運作之前讓你撰寫正確的規則 — 會阻塞入門。所以主控台在你建立資料庫時提供兩個選項:生產模式 (拒絕一切,你自己撰寫規則) 或測試模式 (30 天允許一切)。大多數開發者點選測試模式,然後就忘了回頭再看。較舊的專案有 30 天計時器;目前的專案則有無自動到期的無限期 if true 規則。

結構性問題:AI 編碼工具在顯示測試模式規則的文件、教學與 Stack Overflow 回答上訓練。當你問 Cursor 或 Claude Code「如何設定 Firebase」時,答案經常包含完全相同的 allow read, write: if true 區塊,彷彿這就是生產規則。AI 並不知道 — 也沒有被提示去知道 — 此規則對生產來說並不安全。

攻擊者看到什麼

具體來說,知道你 Firebase 專案 ID (可從任何已部署應用程式的套件中 30 秒內擷取) 並執行以下內容的攻擊者,可以列出每個集合中的每個文件:

單一未驗證的 curl 請求就足以列舉每個集合。見下方醒目提示區塊。

bash
curl 'https://firestore.googleapis.com/v1/projects/[project-id]/databases/(default)/documents:listCollectionIds' \
  -X POST \
  -H 'Content-Type: application/json' \
  -d '{}'

回應是頂層集合的完整清單。對每個集合,第二個請求傳回文件。此路徑沒有速率限制,因為 if true 規則接受匿名流量。我們見過在不到一小時內被列舉的擁有數百萬文件的 Firebase 資料庫。

在寫入路徑上:帶有 {fields} 的單一 POST 會建立新文件。攻擊者可以用垃圾汙染你的集合、汙損從 Firestore 讀取的使用者面頁面,或將你的資料庫作為免費的訊息代理 — 你的使用帳單暴增、你開始調查,帳單解釋了問題。

四個生產安全的替代方案

選擇符合你應用程式資料模型的替代方案。所有四個都假設你已有使用者驗證 (Firebase Auth 或任何發行 Firebase ID 權杖的提供者):

選項 1:使用者擁有的文件

最常見的 SaaS 樣式。文件位於 /users/{userId}/... 之下,只有擁有者能接觸它們。match /users/{userId}/{document=**} { allow read, write: if request.auth != null && request.auth.uid == userId; }

firebase
match /users/{userId}/{document=**} {
  allow read, write: if request.auth != null
                     && request.auth.uid == userId;
}

選項 2:每個文件上的擁有者欄位

當文件位於平坦集合 (未巢狀於使用者 ID 之下) 中時,儲存 owner_uid 欄位並檢查它。match /posts/{postId} { allow read: if resource.data.public == true || resource.data.owner_uid == request.auth.uid; allow write: if request.auth.uid == resource.data.owner_uid; }

firebase
match /posts/{postId} {
  allow read:  if resource.data.public == true
              || resource.data.owner_uid == request.auth.uid;
  allow write: if request.auth.uid == resource.data.owner_uid;
}

選項 3:多租戶組織隔離

適用於具有組織範圍資料的 B2B SaaS。在每個文件上儲存 org_id 欄位,並比對使用者的自訂宣告。allow read, write: if request.auth.token.org_id == resource.data.org_id;。需要在註冊期間透過 Firebase Admin SDK 設定自訂宣告。

firebase
allow read, write: if request.auth.token.org_id == resource.data.org_id;

選項 4:唯讀的公開內容

適用於行銷內容、公開個人檔案、產品目錄 — 任何真正公開讀取、僅管理員可寫入的內容。match /products/{productId} { allow read: if true; allow write: if request.auth.token.admin == true; }admin 自訂宣告只在管理員帳號上設定。

firebase
match /products/{productId} {
  allow read:  if true;
  allow write: if request.auth.token.admin == true;
}

快速稽核查詢

在修復前,確認 if true 是否確實生效。開啟 Firebase 主控台 → Firestore → Rules 並搜尋 if true。若你在註解之外的任何地方找到它,就有一項開放規則發現。同一個 UI 中的規則模擬器讓你能在本機重放攻擊者的請求 — 貼上一個匿名的 GET /users/somebody 並確認模擬器傳回 Allowed

外部確認:對你的生產 URL 執行 FixVibe 掃描。baas.firebase-rules 檢查會探測你的 Firestore、Realtime Database 與 Storage 規則,並回報攻擊者會發現的相同發現 — 獨立於 Firebase 主控台所顯示的內容。

常見問題

<code>if true</code> 與 <code>if request.auth != null</code> 有什麼差別?

if true 允許匿名存取 — 網際網路上的任何人。if request.auth != null 要求任何已登入的使用者,這比較好,但仍然錯誤:你應用程式的任何使用者都能讀取其他每個使用者的資料。生產規則必須透過 request.auth.uid == resource.data.owner_uid 或類似方式限定到特定使用者或組織。

Firebase 會自動讓 <code>if true</code> 規則到期嗎?

較舊的專案 (2023 年前) 有 30 天計時器,會將 if true 規則轉換為 if false。目前的專案沒有 — 規則會無限期存續直到手動替換。如果你的專案是 2023 年前建立的,而規則看起來沒問題,請再次檢查:計時器可能已將它們翻轉為 if false,這會阻塞你自己的應用程式。

我可以使用未來日期的時間戳檢查作為安全網嗎?

不能 — 時間戳條件並非安全控制。它在某個未來日期讓開放規則到期,這代表在那個日期之前攻擊者擁有完整存取權。而且你會忘掉那個日期。用以驗證為範圍的規則取代 if true,而不是受時間限制的規則。

如果我的應用程式真的是公開讀取 (部落格、產品目錄) 怎麼辦?

那就明確地寫 allow read: if true; allow write: if false;,只在公開集合上 — 不是在資料庫中的每個集合上。每個集合使用獨立的 match 子句,並且絕對不要在可寫的規則上使用遞迴 {document=**} 萬用字元。

後續步驟

對你的生產 URL 執行 FixVibe 掃描 — baas.firebase-rules 檢查會確認 if true 目前是否可從網際網路被利用。關於掃描器機制以及對 Realtime Database 和 Storage 的並行偵測,請參閱 Firebase 規則掃描器。關於 Supabase 上的對應設定錯誤類別,請閱讀 Supabase RLS 掃描器

// 掃描你的 baas 介面

在別人之前找到開放的資料表。

輸入一個生產 URL。FixVibe 會列舉你的應用程式通訊的 BaaS 提供者、識別其公開端點,並回報未經驗證的用戶端可以讀取或寫入什麼。免費、無需安裝、不需信用卡。

  • 免費方案 — 每月 3 次掃描,註冊免信用卡。
  • 被動 BaaS 指紋識別 — 不需要網域所有權驗證。
  • Supabase、Firebase、Clerk、Auth0、Appwrite 等。
  • 每項發現都附 AI 修復提示 — 可貼回 Cursor / Claude Code。
Firebase allow read, write: if true 解析:它做什麼以及如何修復 — Docs · FixVibe