// 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 測試模式規則文件是六行:
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 並不知道 — 也沒有被提示去知道 — 此規則對生產來說並不安全。
攻擊者看到什麼
具體來說,知道你 Firebase 專案 ID (可從任何已部署應用程式的套件中 30 秒內擷取) 並執行以下內容的攻擊者,可以列出每個集合中的每個文件:
單一未驗證的 curl 請求就足以列舉每個集合。見下方醒目提示區塊。
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; }
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。
外部確認:對你的生產 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 掃描器。
