// docs / baas security / firebase if-true explainer
Firebase allow read, write: if true 解析:它做什麼以及如何修復
allow read, write: if true; 是生產中最常見的單一 Firebase 設定錯誤。它是建立新資料庫時 Firebase 主控臺所建議的測試模式預設值、AI 編碼工具從文件再生的規則,以及向網際網路上任何人開放整個 Firestore 資料庫的規則。本文精確解釋語法、展示此規則生效時攻擊者看到什麼,並提供四個適合不同使用情境、逐步更嚴格的替代方案。
逐行語法解析
一份完整的 Firestore 測試模式規則文件是六行:
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;是規則主體。read與write都被允許;條件if true,嗯,永遠為真。read涵蓋get與list操作;write涵蓋create、update與delete。
淨效果:任何持有 Firebase 專案 ID 並擁有正確 SDK 的用戶端,皆可讀取或寫入任何集合中的任何文件。不需要驗證。不強制速率限制。
Firebase 為何將此作為預設值
Firebase 希望你在建立專案後的前 30 秒內就能開始寫程式。替代方案 — 在任何讀寫運作之前讓你撰寫正確的規則 — 會阻塞入門。所以主控臺在你建立資料庫時提供兩個選項:生產模式 (拒絕一切,你自己撰寫規則) 或測試模式 (30 天允許一切)。大多數開發者點選測試模式,然後就忘了回頭再看。較舊的專案有 30 天計時器;目前的專案則有無自動到期的無限期 if true 規則。
結構性問題:AI 編碼工具在顯示測試模式規則的文件、教學與 Stack Overflow 回答上訓練。當你問 Cursor 或 Claude Code「如何設定 Firebase」時,答案經常包含完全相同的 allow read, write: if true 區塊,彷彿這就是生產規則。AI 並不知道 — 也沒有被提示去知道 — 此規則對生產來說並不安全。
攻擊者看到什麼
Concretely, an attacker who knows your Firebase project ID (it ships in every deployed app's configuration) can list every collection and read every document with plain, unauthenticated requests to Firebase's public REST API.
Once the collections are listed, every document in them can be read. Nothing slows this down, because if true rules accept anonymous traffic.
在寫入路徑上:帶有 {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; }
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; }
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 設定自訂宣告。
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 自訂宣告只在管理員帳號上設定。
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。
External confirmation: run a FixVibe scan against your production URL. FixVibe checks your Firestore, Realtime Database, and Storage rules from the outside and reports what an attacker would find — independent of what the Firebase Console shows.
常見問題
if true 與 if request.auth != null 有什麼差別?
if true 允許匿名存取 — 網際網路上的任何人。if request.auth != null 要求任何已登入的使用者,這比較好,但仍然錯誤:你應用程式的任何使用者都能讀取其他每個使用者的資料。生產規則必須透過 request.auth.uid == resource.data.owner_uid 或類似方式限定到特定使用者或組織。
Firebase 會自動讓 if true 規則到期嗎?
較舊的專案 (2023 年前) 有 30 天計時器,會將 if true 規則轉換為 if false。目前的專案沒有 — 規則會無限期存續直到手動替換。如果你的專案是 2023 年前建立的,而規則看起來沒問題,請再次檢查:計時器可能已將它們翻轉為 if false,這會阻塞你自己的應用程式。
我可以使用未來日期的時間戳檢查作為安全網嗎?
不能 — 時間戳條件並非安全控制。它在某個未來日期讓開放規則到期,這代表在那個日期之前攻擊者擁有完整存取權。而且你會忘掉那個日期。用以驗證為範圍的規則取代 if true,而不是受時間限制的規則。
如果我的應用程式真的是公開讀取 (部落格、產品目錄) 怎麼辦?
那就明確地寫 allow read: if true; allow write: if false;,只在公開集合上 — 不是在資料庫中的每個集合上。每個集合使用獨立的 match 子句,並且絕對不要在可寫的規則上使用遞迴 {document=**} 萬用字元。
後續步驟
Run a FixVibe scan against your production URL — it confirms whether if true is currently exploitable from the public internet. For how the scanner covers Realtime Database and Storage as well, see Firebase rules scanner. For the equivalent class of misconfiguration on Supabase, read Supabase RLS scanner.
