כללי אבטחה לפעולות בצינור

למרות שפעולות Pipeline מציעות מגוון רחב של תכונות, מנוע הכללים מוגבל לזיהוי של מסנני השוואה (למשל >) ולוגיים (למשל or) כדי להבטיח את האפשרות לספק אילוצים ואת האבטחה.

ביטויי סינון נתמכים

כדי שהפעולות בצינור יוגבלו לגבולות שהוגדרו בכללים, צריך להשתמש באופרטורים לוגיים ובאופרטורים להשוואה מול קבועים. מנוע הכללים מזהה את סוגי המסננים הבאים:

  • השוואות: eq, neq, gt, gte, lt, lte, in, arrayContains.
  • Logical: and, or.

הנה כמה דוגמאות:

  • where(eq("foo", 2))
  • where(lt("foo", 2))
  • documents("/user/1", "/user/2").where(...)

מאפייני הבקשה

אפשר להמשיך להשתמש באובייקט request כדי לאמת את האימות ואת הקשר השאילתה, אבל חלק מהמאפיינים שזמינים בשאילתות רגילות לא נתמכים בפעולות של צינורות.

מאפיינים נתמכים

המנוע החדש ממשיך לתמוך במאפיינים הבאים:

  • request.auth: גישה לנתוני uid ואסימון של משתמש.
  • request.method: מזהה את הפעולה (לדוגמה, get, ‏ list).
  • request.path: הנתיב של המשאב שאליו מתבצעת גישה.
  • request.time: חותמת הזמן בצד השרת של הבקשה.

מאפיינים שלא נתמכים

המאפיינים של request.query, כמו limit,‏ offset ו-orderBy, לא נתמכים בבדיקות של כללי פעולות בצינורות עיבוד נתונים, כי קשה לקבוע את הערכים האלה בשאילתות מרובות שלבים.

טיפול בשלב בצינור עיבוד נתונים והרשאות

יש שלבים שונים בצינור הנתונים שממופים לפעולות ספציפיות ומפורטות בכללי האבטחה:

  • הרשאות allow list: מופעלות על ידי שלבים collection(), collectionGroup() ו-database().
  • הרשאות allow get: מופעלות בשלב documents(), שמתייחסים אליו באופן דומה לפעולת get אצווה.
  • שלב Literals: השלב literals() לא קורא מהמסד הנתונים, אבל יכול להיות שיהיו בו עלויות. כדי למנוע שימוש לרעה, צריך לשלב אותו עם שלב אחר (כמו collection()) שאפשר לאמת באמצעות כללים.

שלבי השינוי של השדה

הכללים פועלים רק על נתונים מאוחסנים ולא על ערכים נגזרים. אם צינור כולל שלבים שמשנים שדות (לדוגמה, add_fields(...),‏ replace_with(...),‏ select(...),‏ remove_fields(...)), מנוע הכללים מפסיק להחיל אילוצי סינון אחרי השלב הזה. כדי לוודא שהכללים פועלים כמצופה, צריך למקם את שלבי המסנן (כלומר where) לפני שלבים שיכולים לשנות את המסמכים המקוריים שמאוחסנים.

לדוגמה, ניקח את כלל האבטחה הבא:

match /databases/{database}/documents {
  match /cities/{city} {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    allow read: if resource.data.visibility == 'public';
  }
}

נדחה: הכלל הזה דוחה את צינור העיבוד הבא כי השלב addFields מתרחש לפני הסינון למסמכים שבהם visibility הוא public:

const results = await db.pipeline()
  .collection("/cities")
  // Filters after a modification stage are ignored by Rules.
  .addFields(constant(1000).as("population"))
  .where(eq(field("visibility"), constant("public")))
  .execute();

מותר: הכלל הזה מאפשר את צינור הנתונים הבא כי השלב where(eq(field("visibility"), constant("public"))) מתרחש לפני כל שלבי השינוי:

const results = await db.pipeline()
  .collection("/cities")
  .where(eq(field("visibility"), constant("public")))
  .addFields(constant(1000).as("population"))
  .execute();