از این راهنما برای درک آسیبپذیریهای رایج در پیکربندیهای Firebase Security Rules استفاده کنید، قوانین خود را بررسی و ایمنتر کنید و تغییرات خود را قبل از استقرار آزمایش کنید.
اگر هشداری دریافت کردید که اطلاعات شما به درستی ایمن نشده است، این خطاهای رایج را بررسی کنید و قوانین آسیب پذیر را به روز کنید.
Firebase Security Rules خود دسترسی پیدا کنید
برای مشاهده Rules موجود خود، از Firebase CLI یا کنسول Firebase استفاده کنید. مطمئن شوید که قوانین خود را با استفاده از روش یکسان و به طور مداوم ویرایش می کنید تا از بازنویسی اشتباه به روز رسانی ها جلوگیری کنید. اگر مطمئن نیستید که آیا قوانین تعریف شده محلی شما جدیدترین بهروزرسانیها را منعکس میکنند یا خیر، کنسول Firebase همیشه آخرین نسخه اجرا شده از Firebase Security Rules شما را نشان میدهد.
برای دسترسی به قوانین خود از کنسول Firebase ، پروژه خود را انتخاب کنید، سپس به Realtime Database ، Cloud Firestore یا Storage بروید. هنگامی که در پایگاه داده یا سطل ذخیره سازی صحیح قرار گرفتید روی Rules کلیک کنید.
برای دسترسی به قوانین خود از Firebase CLI، به فایل قوانین ذکر شده در فایل firebase.json خود بروید.
Firebase Security Rules را بدانید
Firebase Security Rules از داده های شما در برابر کاربران مخرب محافظت می کند. هنگامی که یک نمونه پایگاه داده یا سطل Cloud Storage را در کنسول Firebase ایجاد میکنید، میتوانید انتخاب کنید که دسترسی به همه کاربران را رد کنید ( حالت قفل شده ) یا به همه کاربران اجازه دسترسی بدهید ( حالت آزمایشی ). در حالی که ممکن است بخواهید پیکربندی بازتری در طول توسعه داشته باشید، مطمئن شوید که قبل از استقرار برنامه خود، برای پیکربندی صحیح قوانین و ایمن سازی داده های خود وقت صرف کرده اید.
همانطور که در حال توسعه برنامه خود و آزمایش پیکربندی های مختلف برای قوانین خود هستید، از یکی از شبیه سازهای Firebase محلی برای اجرای برنامه خود در یک محیط توسعه محلی استفاده کنید.
سناریوهای رایج با قوانین ناامن
Rules که ممکن است بهطور پیشفرض تنظیم کرده باشید یا همانطور که در ابتدا روی توسعه برنامه خود کار میکردید، باید قبل از استقرار برنامه خود بازبینی و بهروزرسانی شوند. با اجتناب از مشکلات رایج زیر، مطمئن شوید که به درستی داده های کاربران خود را ایمن می کنید.
دسترسی را باز کنید
همانطور که پروژه Firebase خود را راهاندازی میکنید، ممکن است قوانین خود را طوری تنظیم کرده باشید که اجازه دسترسی باز را در طول توسعه بدهید. ممکن است فکر کنید تنها فردی هستید که از برنامه خود استفاده می کنید، اما اگر آن را اجرا کرده اید، در اینترنت در دسترس است. اگر کاربران را احراز هویت نمی کنید و قوانین امنیتی را پیکربندی نمی کنید، هر کسی که ID پروژه شما را حدس بزند می تواند داده ها را بدزدد، تغییر دهد یا حذف کند.
توصیه نمی شود: دسترسی خواندن و نوشتن برای همه کاربران. // Allow read/write access to all users under any conditions // Warning: **NEVER** use this ruleset in production; it allows // anyone to overwrite your entire database. service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if true; } } } { // Allow read/write access to all users under any conditions // Warning: **NEVER** use this ruleset in production; it allows // anyone to overwrite your entire database. "rules": { ".read": true, ".write": true } } // Anyone can read or write to the bucket, even non-users of your app. // Because it is shared with App Engine, this will also make // files uploaded using App Engine public. // Warning: This rule makes every file in your Cloud Storage bucket accessible to any user. // Apply caution before using it in production, since it means anyone // can overwrite all your files. service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write; } } } |
راه حل: قوانینی که دسترسی خواندن و نوشتن را محدود می کند. قوانینی بسازید که برای سلسله مراتب داده های شما منطقی باشد. یکی از راه حل های رایج برای این ناامنی، امنیت مبتنی بر کاربر با Firebase Authentication است. درباره احراز هویت کاربران با قوانین بیشتر بیاموزید. فقط صاحب محتواservice cloud.firestore { match /databases/{database}/documents { // Allow only authenticated content owners access match /some_collection/{document} { // Allow reads and deletion if the current user owns the existing document allow read, delete: if request.auth.uid == resource.data.author_uid; // Allow creation if the current user owns the new document allow create: if request.auth.uid == request.resource.data.author_uid; // Allow updates by the owner, and prevent change of ownership allow update: if request.auth.uid == request.resource.data.author_uid && request.auth.uid == resource.data.author_uid; } } } دسترسی مختلط عمومی و خصوصیservice cloud.firestore { match /databases/{database}/documents { // Allow public read access, but only content owners can write match /some_collection/{document} { // Allow public reads allow read: if true // Allow creation if the current user owns the new document allow create: if request.auth.uid == request.resource.data.author_uid; // Allow updates by the owner, and prevent change of ownership allow update: if request.auth.uid == request.resource.data.author_uid && request.auth.uid == resource.data.author_uid; // Allow deletion if the current user owns the existing document allow delete: if request.auth.uid == resource.data.author_uid; } } } فقط صاحب محتوا{ "rules": { "some_path": { "$uid": { // Allow only authenticated content owners access to their data ".read": "auth !== null && auth.uid === $uid", ".write": "auth !== null && auth.uid === $uid" } } } } دسترسی مختلط عمومی و خصوصی{ // Allow anyone to read data, but only authenticated content owners can // make changes to their data "rules": { "some_path/$uid": { ".read": true, // or ".read": "auth.uid !== null" for only authenticated users ".write": "auth.uid === $uid" } } } فقط صاحب محتوا// Grants a user access to a node matching their user ID service firebase.storage { match /b/{bucket}/o { // Files look like: "user/<UID>/file.txt" match /user/{userId}/{fileName} { allow read, write: if request.auth.uid == userId; } } } دسترسی مختلط عمومی و خصوصیservice firebase.storage { match /b/{bucket}/o { // Files look like: "user/<UID>/file.txt" match /user/{userId}/{fileName} { allow read; allow write: if request.auth.uid == userId; } } } |
دسترسی برای هر کاربر احراز هویت شده
گاهی اوقات، Rules بررسی میکند که کاربر وارد سیستم شده است، اما دسترسی را بر اساس آن احراز هویت محدود نمیکند. اگر یکی از قوانین شما شامل auth != null
، تأیید کنید که میخواهید هر کاربر وارد شده به دادهها دسترسی داشته باشد.
توصیه نمی شود: هر کاربری که وارد سیستم شده است به کل پایگاه داده شما دسترسی خواندن و نوشتن دارد. service cloud.firestore { match /databases/{database}/documents { match /some_collection/{document} { allow read, write: if request.auth.uid != null; } } } { "rules": { ".read": "auth.uid !== null", ".write": "auth.uid !== null" } } // Only authenticated users can read or write to the bucket service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } } } |
راه حل: دسترسی محدود با استفاده از شرایط امنیتی. هنگامی که در حال بررسی احراز هویت هستید، ممکن است بخواهید از یکی از ویژگی های احراز هویت برای محدود کردن بیشتر دسترسی به کاربران خاص برای مجموعه داده های خاص استفاده کنید. درباره ویژگی های مختلف احراز هویت بیشتر بیاموزید. دسترسی مبتنی بر نقشservice cloud.firestore { match /databases/{database}/documents { // Assign roles to all users and refine access based on user roles match /some_collection/{document} { allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader" allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer" // Note: Checking for roles in your database using `get` (as in the code // above) or `exists` carry standard charges for read operations. } } } دسترسی مبتنی بر ویژگی// Give each user in your database a particular attribute // and set it to true/false // Then, use that attribute to grant access to subsets of data // For example, an "administrator" attribute set // to "true" grants write access to data service cloud.firestore { match /databases/{database}/documents { match /some_collection/{document} { allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true; allow read: true; } } } دسترسی مختلط عمومی و خصوصیservice cloud.firestore { match /databases/{database}/documents { // Allow public read access, but only content owners can write match /some_collection/{document} { allow read: if true allow write: if request.auth.uid == request.resource.data.author_uid } } } فقط صاحب محتوا{ "rules": { "some_path": { "$uid": { // Allow only authenticated content owners access to their data ".read": "auth.uid === $uid", ".write": "auth.uid === $uid" } } } } دسترسی مشخص شده در مسیر{ "rules": { "some_path/$uid": { ".write": "auth.uid === $uid", // Create a "public" subpath in your dataset "public": { ".read": true // or ".read": "auth.uid !== null" }, // Create a "private" subpath in your dataset "private": { ".read": "auth.uid === $uid" } } } } دسترسی مختلط عمومی و خصوصی{ // Allow anyone to read data, but only authenticated content owners can // make changes to their data "rules": { "some_path/$uid": { ".read": true, // or ".read": "auth.uid !== null" for only authenticated users ".write": "auth.uid === $uid" } } } دسترسی مبتنی بر گروه// Allow reads if the group ID in your token matches the file metadata `owner` property // Allow writes if the group ID is in the user's custom token match /files/{groupId}/{fileName} { allow read: if resource.metadata.owner == request.auth.token.groupId; allow write: if request.auth.token.groupId == groupId; } فقط صاحب محتوا// Grants a user access to a node matching their user ID service firebase.storage { match /b/{bucket}/o { // Files look like: "user/<UID>/file.txt" match /user/{userId}/{fileName} { allow read, write: if request.auth.uid == userId; } } } دسترسی مختلط عمومی و خصوصیservice firebase.storage { match /b/{bucket}/o { // Files look like: "user/<UID>/file.txt" match /user/{userId}/{fileName} { allow read; allow write: if request.auth.uid == userId; } } } |
( Realtime Database ) قوانین نادرست به ارث رسیده
Realtime Database Security Rules بیدرنگ آبشاری میکنند، با قوانینی در مسیرهای کمعمقتر و والد، قوانین را در گرههای عمیقتر و فرعی نادیده میگیرند. هنگامی که یک قانون را در یک گره فرزند می نویسید، به یاد داشته باشید که این قانون فقط می تواند امتیازات اضافی را اعطا کند. شما نمی توانید دسترسی به داده ها را در مسیر عمیق تری در پایگاه داده خود اصلاح یا لغو کنید.
توصیه نمی شود: اصلاح قوانین در مسیرهای کودک { "rules": { "foo": { // allows read to /foo/* ".read": "data.child('baz').val() === true", "bar": { /* ignored, since read was allowed already */ ".read": false } } } } |
راه حل: قوانینی را در مسیرهای والد بنویسید که گسترده هستند، و امتیازات خاص تری را در مسیرهای فرزند اعطا کنید اگر نیازهای دسترسی به داده شما به جزئیات بیشتری نیاز دارد، قوانین خود را دقیق نگه دارید. درباره Realtime Database Security Rules در دستور اصلی Realtime Database Security Rules بیشتر بیاموزید. |
دسترسی بسته
در حالی که در حال توسعه برنامه خود هستید، یکی دیگر از روش های رایج این است که داده های خود را قفل نگه دارید. به طور معمول، این بدان معناست که دسترسی خواندن و نوشتن را برای همه کاربران به شرح زیر بسته اید:
// Deny read/write access to all users under any conditions service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if false; } } }
{ "rules": { ".read": false, ".write": false } }
// Access to files through Cloud Storage is completely disallowed. // Files may still be accessible through App Engine or Google Cloud Storage APIs. service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if false; } } }
Firebase Admin SDK و توابع Cloud همچنان می توانند به پایگاه داده شما دسترسی داشته باشند. زمانی که قصد دارید از Cloud Firestore یا Realtime Database به عنوان یک Backend فقط سرور در ارتباط با Firebase Admin SDK استفاده کنید، از این قوانین استفاده کنید. در حالی که ایمن است، باید آزمایش کنید که کلاینت های برنامه شما می توانند داده ها را به درستی بازیابی کنند.
درباره Cloud Firestore Security Rules و نحوه عملکرد آنها در Get Started with Cloud Firestore Security Rules بیشتر بیاموزید.
Cloud Firestore Security Rules خود را آزمایش کنید
برای بررسی رفتار برنامهتان و تأیید پیکربندیهای Cloud Firestore Security Rules ، از شبیهساز Firebase استفاده کنید. قبل از اعمال هرگونه تغییر، از شبیه ساز Cloud Firestore برای اجرا و خودکارسازی تست های واحد در یک محیط محلی استفاده کنید.
برای تأیید سریع Firebase Security Rules در کنسول Firebase ، از Firebase Rules Simulator استفاده کنید.