// docs / baas security / firebase rules scanner
Firebase 규칙 스캐너: 열린 Firestore, Realtime Database, Storage 규칙 찾기
Firebase 앱은 일관된 방식으로 보안에 실패합니다: 테스트 모드 빠른 시작에서 남은 <code>allow read, write: if true;</code> 규칙이 프로덕션 전에 결코 교체되지 않습니다. AI 코딩 도구는 이러한 규칙을 문서 예제에서 그대로 생성하며 개발자에게 강화하도록 거의 안내하지 않습니다. 이 기사는 Firebase 규칙 스캐너가 Firestore, Realtime Database, Cloud Storage에 걸쳐 프로젝트 외부에서 열린 규칙을 어떻게 탐지하는지 — 그리고 발견된 것을 어떻게 고치는지를 보여줍니다.
스캐너가 열린 Firebase 규칙을 찾는 방법
Firebase 서비스는 잘 알려지고 예측 가능한 URL 모양을 노출합니다. 자격 증명이 없는 스캐너는 각각을 탐사하고 익명 읽기가 성공하는지 관찰할 수 있습니다. FixVibe의 baas.firebase-rules 검사는 Firebase 서비스당 하나씩 세 개의 독립적인 탐사로 실행됩니다:
- <strong>Firestore.</strong> The scanner extracts the project ID from the deployed app's bundle (it's in <code>firebase.initializeApp({ projectId: ... })</code>), then issues <code>GET https://firestore.googleapis.com/v1/projects/[project-id]/databases/(default)/documents/[collection]:listDocuments</code> against common collection names. A <code>200 OK</code> with documents in the response means <code>allow read</code> is permissive.
- Realtime Database. 스캐너는
https://[project-id]-default-rtdb.firebaseio.com/.json을 탐사합니다. 루트가 익명으로 읽을 수 있으면 응답은 JSON으로서 전체 데이터베이스 트리입니다. 더 보수적인 테스트는.json?shallow=true를 쿼리하여 최상위 키만 반환합니다 — 어느 쪽이든 발견입니다. - Cloud Storage. 스캐너는
https://firebasestorage.googleapis.com/v0/b/[project-id].appspot.com/o을 쿼리합니다. 응답이 인증 없이 파일 이름을 나열하면 버킷은 익명 나열 가능합니다. 개별 파일 다운로드가 거부되더라도 나열 가능한 스토리지는 발견입니다 — 공격자는 버킷을 열거하여 추측 가능한 파일 이름을 찾습니다.
테스트 모드 함정이 실제로 어떤 모습인지
Firebase의 빠른 시작 문서에는 인터넷에서 가장 많이 복사된 규칙 블록 중 하나가 포함되어 있습니다:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}Firebase는 이전에 이러한 규칙에 자동 30일 만료를 추가했습니다. 변경되었습니다: 오늘날 개발자가 교체하지 않는 한 규칙은 영원히 지속됩니다. AI 코딩 도구는 — 테스트 모드 블록을 포함하는 수년간의 문서로 훈련되어 — 이를 그대로 자주 내보내며 개발자에게 "이것이 보안 규칙입니다"라고 말합니다. 그렇지 않습니다.
프로덕션에 나타나지만 똑같이 허용적인 다른 변형:
// future-date variant — equivalent to "if true" allow read, write: if request.time < timestamp.date(2099, 1, 1); // authenticated-user variant — any signed-in user reads and writes anything allow read: if true; allow write: if request.auth != null; // any-auth variant — any signed-in user owns every document allow read, write: if request.auth != null;
- 미래 타임스탬프 변형: 먼 미래 날짜까지 모든 것을 허용하는 규칙. 사실상 결코 만료되지 않습니다(위의 강조된 블록 참조).
allow read: if true; allow write: if request.auth != null;— 공개 읽기, 모든 인증된 사용자가 쓸 수 있음.allow read, write: if request.auth != null;— 로그인한 모든 사용자가 다른 사용자의 데이터를 포함한 모든 문서를 읽거나 쓸 수 있음.
스캐너가 열린 규칙을 발견했을 때 할 일
열린 Firebase 규칙은 런타임 비상 사태입니다. 수정은 세 서비스 모두 동일한 모양입니다: 모든 규칙을 명시적 소유자 필드에 대해 request.auth.uid로 범위를 좁히세요. 각 서비스는 자체 규칙 구문이 있습니다:
Firestore
match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; }. 경로 세그먼트 바인딩 {userId}가 사용자가 접근할 수 있는 유일한 문서가 됩니다.
match /users/{userId} {
allow read, write: if request.auth != null
&& request.auth.uid == userId;
}Realtime Database
<code>{ "rules": { "users": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid" } } } }</code>. The <code>$uid</code> wildcard captures the path segment for comparison.
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}Cloud Storage
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/{allPaths=**} { allow read, write: if request.auth.uid == userId; } } }. 관례: 파일을 users/[uid]/[filename] 하위에 저장하고 경로가 소유권을 강제하도록 하세요.
service firebase.storage {
match /b/{bucket}/o {
match /users/{userId}/{allPaths=**} {
allow read, write: if request.auth.uid == userId;
}
}
}Firebase CLI를 통해 규칙 배포: firebase deploy --only firestore:rules, firebase deploy --only database, firebase deploy --only storage. FixVibe 스캔을 다시 실행하여 새 규칙이 프로덕션에 있는지 확인하세요 — baas.firebase-rules 발견이 사라져야 합니다.
firebase deploy --only firestore:rules
firebase deploy --only database
firebase deploy --only storageFirebase 내장 도구와의 비교
Firebase Console은 현재 규칙을 보여주지만 런타임 동작에 대해 감사하지 않습니다. Firebase Rules 시뮬레이터는 합성 요청에 대해 규칙 로직을 테스트할 수 있게 합니다 — 유용하지만 로컬입니다. 두 도구 모두 프로덕션 규칙이 공개 인터넷의 익명 공격자에게 실제로 무엇을 반환하는지 알려주지 않습니다. FixVibe(또는 수동 구성이 있는 Burp Suite) 같은 외부 스캐너만이 공격자와 동일한 각도에서 탐사합니다. Google 자체 App Check는 남용을 완화하지만 올바르게 범위가 좁혀진 규칙을 대체하지 않습니다.
자주 묻는 질문
스캐너가 내 Firestore 데이터를 읽거나 수정하나요?
수동 스캔은 규칙이 허용하는지 확인하기 위해 서비스당 최대 한 번의 익명 읽기를 발행합니다. 스캐너는 응답 모양과 데이터의 존재를 기록합니다 — 페이지를 매기지 않고, 문서를 열거하지 않으며, 쓰지 않습니다. 쓰기 탐사는 확인된 도메인 소유권 뒤에서 게이트되며, 확인되지 않은 대상에 대해 결코 실행되지 않습니다.
Firebase 프로젝트가 App Check를 사용하면 어떻게 되나요?
App Check는 인증되지 않은 요청을 403으로 거부합니다. App Check 토큰이 없는 스캐너는 모든 탐사에서 403을 봅니다 — 이것이 올바른 결과입니다. App Check는 규칙 정확성의 대체물이 아니지만(도난당한 App Check 토큰 + 열린 규칙은 여전히 데이터를 유출함), 기회주의적인 외부 스캔을 차단합니다.
스캐너가 부분적인 규칙 설정 오류(읽기 열림, 쓰기 닫힘)를 탐지할 수 있나요?
예 — 각 규칙(allow read, allow write)이 별도로 탐사됩니다. 200 OK로 성공하는 읽기 전용 탐사는 쓰기가 거부되더라도 열린 읽기 발견을 보고합니다. 두 발견은 별개입니다: 데이터 유출과 데이터 조작은 별개의 위험입니다.
사용자 정의 도메인 하에 배포된 Firebase 앱에 대해 작동하나요?
예. 스캐너는 도메인이 아닌 배포된 번들에서 Firebase 프로젝트 ID를 추출합니다. 사용자 정의 도메인, app.web.app 서브도메인, 자체 호스팅된 Firebase 앱은 JavaScript 번들이 도달 가능한 한 모두 동일한 방식으로 작동합니다.
다음 단계
프로덕션 URL에 대해 무료 FixVibe 스캔을 실행하세요 — baas.firebase-rules 검사는 모든 플랜에서 제공되며 Firestore, Realtime Database, Cloud Storage에 걸쳐 열린 규칙을 플래그합니다. allow read, write: if true 패턴에 대한 더 깊은 설명은 Firebase allow read, write: if true 설명을 참조하세요. Supabase, Firebase, Clerk, Auth0 전반에 걸친 포괄적 관점은 BaaS 설정 오류 스캐너를 읽으세요.
