הגדרת מאפייני שפה של כללים מותאמים אישית

לכל כלל במדיניות האבטחה של Google Cloud Armor יש עדיפות, תנאי התאמה ופעולה. ‫Cloud Armor מבצע את הפעולה של הכלל עם העדיפות הכי גבוהה שתואם לבקשה. כללים עם עדיפות נמוכה יותר מהכלל התואם עם העדיפות הכי גבוהה לא נבדקים, גם אם יש להם את אותם תנאי התאמה.

כל כלל במדיניות האבטחה תומך בשני סוגים של תנאי התאמה:

  • תנאי התאמה בסיסי מכיל רשימות של כתובות IP או רשימות של טווחי כתובות IP. כשיוצרים כלל באמצעות Google Cloud CLI, מגדירים תנאי התאמה בסיסיים באמצעות הדגל --src-ip-ranges.
  • תנאי התאמה מתקדם מכיל ביטוי עם עד חמישה ביטויי משנה שיכולים להתאים למגוון מאפיינים של בקשה נכנסת. תנאי התאמה מתקדמים מוגדרים באמצעות הדגל --expression כשיוצרים כלל באמצעות Google Cloud CLI.

בדף הזה נסביר על תנאי התאמה מתקדמים ועל שפת הכללים המותאמים אישית של Cloud Armor, שמשמשת לכתיבת ביטויים בתנאי ההתאמה המתקדמים של כללי מדיניות האבטחה. השפה של הכללים בהתאמה אישית ב-Cloud Armor היא קבוצת משנה של Common Expression Language‏ (CEL).

ביטויים שנכתבים בשפה של כללים מותאמים אישית ב-Cloud Armor דורשים שני רכיבים:

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

לדוגמה, הביטוי הבא משתמש במאפיינים origin.ip ו-198.51.100.0/24 בפעולה inIpRange. במקרה הזה, הביטוי מחזיר true אם origin.ip נמצא בטווח כתובות ה-IP של 198.51.100.0/24.

inIpRange(origin.ip, '198.51.100.0/24')

למרות שביטוי הדוגמה הקודמת תואם רק לכתובת ה-IP של הלקוח, כשמשתמשים בביטוי הדוגמה בכלל של מדיניות אבטחה של Cloud Armor, הכלל נחשב לכלל עם תנאי התאמה מתקדמים מנקודת מבט של מכסה. מידע נוסף מופיע במאמר בנושא מכסות ומגבלות של Cloud Armor.

תפעול

במאמר הזה מוסבר על האופרטורים שאפשר להשתמש בהם עם מאפיינים (שמיוצגים על ידי x,‏ y ו-k) כדי להגדיר ביטויי כללים.

תפעול ביטויים תיאור
שוויון x == y הפונקציה מחזירה את הערך true אם x שווה ל-y.
שוויון, מחרוזת מילולית x == "foo" הפונקציה מחזירה את הערך true אם x שווה למחרוזת הקבועה שצוינה.
שוויון, מחרוזת גולמית x == R"fo'o" הפונקציה מחזירה את הערך true אם x שווה למחרוזת הליטרלית הגולמית שצוינה, שלא מפרשת רצפי escape. ליטרלים של מחרוזות גולמיות נוחים לשימוש כשרוצים להביע מחרוזות שצריך להשתמש בהן בתווי בריחה.
שלילה לוגית !x הפונקציה מחזירה את הערך true אם הערך הבוליאני x הוא false, או מחזירה את הערך false אם הערך הבוליאני x הוא true.
אי-שוויון x != y הפונקציה מחזירה את הערך true אם x לא שווה ל-y.
שרשור x + y הפונקציה מחזירה את המחרוזת המחוברת xy.
Logical AND x && y הפונקציה מחזירה את הערך true אם גם x וגם y הם true.
או x || y הפונקציה מחזירה את הערך true אם x,‏ y או שניהם הם true.
מכיל מחרוזת משנה x.contains(y) הפונקציה מחזירה את הערך true אם המחרוזת x מכילה את מחרוזת המשנה y.
מתחיל עם מחרוזת משנה x.startsWith(y) הפונקציה מחזירה את הערך true אם המחרוזת x מתחילה במחרוזת המשנה y.
מסתיים במחרוזת משנה x.endsWith(y) הפונקציה מחזירה את הערך true אם המחרוזת x מסתיימת במחרוזת המשנה y.
התאמה של ביטוי רגיל x.matches(y) הפונקציה מחזירה את הערך true אם המחרוזת x תואמת באופן חלקי לתבנית y של RE2 שצוינה. התבנית RE2 עוברת קומפילציה באמצעות האפשרות RE2::Latin1 שמשביתה את תכונות Unicode.
כתובת IP בטווח inIpRange(x, y) הפונקציה מחזירה את הערך true אם כתובת ה-IP‏ x נכללת בטווח כתובות ה-IP‏ y.
אותיות קטנות x.lower() הפונקציה מחזירה את הערך באותיות קטנות של המחרוזת x.
אותיות רישיות x.upper() הפונקציה מחזירה את הערך באותיות רישיות של המחרוזת x.
ערך מפוענח בקידוד Base64 x.base64Decode() הפונקציה מחזירה את הערך המפוענח בקידוד Base64 של x. לפני כן, התווים קו תחתון (_) ומקף (-) מוחלפים בקו נטוי (/) ובסימן פלוס (+), בהתאמה. הפונקציה מחזירה "" (מחרוזת ריקה) אם x הוא לא ערך תקין של base64.
ערך של מיפוי מקשים m['k'] הפונקציה מחזירה את הערך במפתח k במפה של מחרוזת למחרוזת m אם k זמין. אחרת, היא מחזירה שגיאה. הגישה המומלצת היא קודם לבדוק את הזמינות באמצעות "has(m['k'])==true".
בדיקת הזמינות של מפתחות במפה has(m['k']) הפונקציה מחזירה true אם המפתח k זמין במפה m.
המרה למספר שלם int(x) הפונקציה ממירה את התוצאה של המחרוזת x לסוג int. אחר כך אפשר להשתמש בו כדי לבצע השוואה בין מספרים שלמים באמצעות אופרטורים אריתמטיים רגילים כמו > ו-<=. הפעולה הזו אפשרית רק עבור ערכים שאמורים להיות מספרים שלמים.
אורך size(x) הפונקציה מחזירה את אורך המחרוזת x.
פענוח כתובת URL x.urlDecode() הפונקציה מחזירה את הערך של x אחרי פענוח כתובת ה-URL. רצפי תווים בפורמט %## מוחלפים בערכים המקבילים שאינם ASCII, ו-+ מוחלף ברווח. קידודים לא תקינים מוחזרים כמו שהם.
פענוח כתובת URL (Unicode) x.urlDecodeUni() הפונקציה מחזירה את הערך של x אחרי פענוח ה-URL. בנוסף ל-urlDecode(), היא מטפלת גם ברצפים של תווי Unicode בפורמט %u###. קידודים לא תקינים מוחזרים כמו שהם.
המרת utf8 ל-Unicode x.utf8ToUnicode() הפונקציה מחזירה את הייצוג ב-Unicode של x בקידוד UTF-8 באותיות קטנות.
קיים m.exists(k, expr) הפונקציה מחזירה true אם לפחות רשומה אחת במפה m עומדת בתנאי expr, כאשר k מייצג את המפתח של כל רשומה במפה.
קיים אחד m.exists_one(k, expr) הפונקציה מחזירה את הערך true אם בדיוק רשומה אחת במפה m עומדת בתנאי expr, כאשר k מייצג את המפתח של כל רשומה במפה.
הכול m.all(k, expr) הפונקציה מחזירה את הערך true אם כל הרשומות במפה m עומדות בתנאי expr, כאשר k מייצג את המפתח של כל רשומה במפה.
מסנן m.filter(k, expr) הפונקציה מחזירה מפה שמכילה רק את הרשומות מהמפה m שבהן הרשומה עומדת בתנאי expr, כאשר k מייצג את המפתח של כל רשומה במפה.
מפה m.map(k, expr) מחזירה רשימה שמכילה את התוצאה של הערכת expr לכל מפתח במיפוי m, כאשר k מייצג את המפתח של כל רשומה במיפוי.

מאפיינים

מאפיינים מייצגים מידע מבקשה נכנסת, כמו כתובת ה-IP של הלקוח או נתיב כתובת ה-URL המבוקשת.

שדה סוג תיאור
origin.ip מחרוזת כתובת ה-IP של הלקוח שיזם את הבקשה.
origin.user_ip מחרוזת כתובת ה-IP של הלקוח המקורי, שכלולה ב-HTTP-HEADER על ידי שרת Proxy במעלה הזרם. לפני שמשתמשים במאפיין הזה, צריך להגדיר את האפשרות userIpRequestHeaders[] בשדה advancedOptionsConfig של מדיניות האבטחה כך שתתאים למקור כמו True-Client-IP,‏ X-Forwarded-For או X-Real-IP. מידע נוסף זמין במאמר בנושא סקירה כללית של כתובות ה-IP של משתמשים.

אם לא מגדירים את האפשרות userIpRequestHeaders[], אם הכותרת שהוגדרה מכילה ערכים לא תקינים של כתובות IP או אם הכותרת שהוגדרה לא קיימת, ערך ברירת המחדל של origin.user_ip הוא origin.ip. מידע נוסף זמין במאמר בנושא securityPolicy.

origin.tls_ja4_fingerprint מחרוזת טביעת אצבע של JA4 TLS/SSL אם הלקוח מתחבר באמצעות HTTPS,‏ HTTP/2 או HTTP/3. אם לא זמין, מוחזרת מחרוזת ריקה.
origin.tls_ja3_fingerprint מחרוזת טביעת אצבע של JA3 TLS/SSL אם הלקוח מתחבר באמצעות ‫HTTPS, HTTP/2 או HTTP/3. אם לא זמין, מוחזרת מחרוזת ריקה.
request.headers מפה מיפוי של כותרות בקשת HTTP ממחרוזת למחרוזת. אם לכותרת יש כמה ערכים, הערך התואם במפה הזו הוא מחרוזת יחידה שמכילה את כל הערכים, מופרדים בפסיקים. המפתחות במפה הזו הם כולם אותיות קטנות. מאזני העומסים החיצוניים של האפליקציות בודקים את כל הכותרות שהתקבלו, וחלות עליהם אותן מגבלות.

אפשר להשתמש ב-method‏ has() כדי לבדוק את הזמינות, למשל has(request.headers['header-key']) && request.headers['header-key'] != 'header-value'.

אפשר לחזור על המיפוי כדי לבדוק גם את המפתחות וגם את הערכים. עם זאת, אפשר להשתמש באופרטורים של איטרציה של מפה (exists(),‏ exists_one(),‏ all(),‏ filter() ו-map()) רק ב-request.headers בשילוב עם request.body או request.params באותו ביטוי – לדוגמה, request.body && request.headers.exists(k, k.lower().startsWith('header-prefix')).

request.body מחרוזת מייצג את גוף הבקשה כמחרוזת גולמית. הוא יכול לייצג נתונים מכל Content-Type. התוכן מאוחסן כמחרוזת ללא ניתוח אוטומטי.
request.params מפה מפה של צמדי מפתח/ערך שמצורפים לכתובת ה-URL או נכללים בגוף של בקשות.
בקשת URI: ‏ name1=value1&name2=value2
גוף בקשת JSON עם Content-Type: application/json:‏
{ "username": "johndoe", "email": "johndoe@example.com" }
גוף בקשת GraphQL POST עם Content-Type: application/graphql:‏
{ Username: "exampleUser", query: "/* other fields */" }
גוף בקשת Form POST עם Content-Type: application/x-www-form-urlencoded:‏
"username=exampleUser&email=johndoe%40example.com"
request.method מחרוזת ה-method של בקשת ה-HTTP.
request.path מחרוזת נתיב כתובת ה-URL של ה-HTTP שהתבקש. כשכותבים כללים שתואמים ל-request.path, מומלץ לבצע נורמליזציה של הנתיב כדי להקל על התאמת התחביר במקרה של קידוד כתובת URL, שינויים באותיות רישיות או לוכסנים הפוכים. מידע נוסף ודוגמאות זמינים במאמר בנושא Path traversal and normalization (מעבר בין נתיבים ונרמול).
request.scheme מחרוזת סכמת כתובות ה-URL מסוג HTTP, כמו http או https. הערכים של המאפיין הזה הם באותיות קטנות.
request.query מחרוזת השאילתה בכתובת ה-URL של HTTP בפורמט name1=value&name2=value2, כפי שהיא מופיעה בשורה הראשונה של בקשת ה-HTTP. לא מתבצע פענוח.
origin.region_code מחרוזת קוד המדינה ב-Unicode שמשויך לכתובת ה-IP של הלקוח, למשל US. אם יוצרים כלל או ביטוי שמשתמשים בקודי מדינה או אזור לפי תקן ISO 3166-1 alpha 2, מערכת Cloud Armor מתייחסת לכל קוד בנפרד. הכללים והביטויים של Cloud Armor משתמשים בקודים האזוריים האלה באופן מפורש כדי לאשר או לדחות בקשות.
origin.asn מספר שלם מספר המערכת האוטונומית (ASN) שמשויך לכתובת ה-IP של הלקוח. מספר ה-ASN הייחודי בעולם נקבע על סמך מפעיל הרשת שתומך בקידומות של כתובות ה-IP שמכילות את כתובת ה-IP של הלקוח.

מאפייני reCAPTCHA

בקטע הזה מפורטים מאפיינים שרלוונטיים רק לטוקנים של reCAPTCHA או לקובצי Cookie של פטור. ביטוי משנה שמבוסס על המאפיינים האלה מחזיר false אם טוקן reCAPTCHA או קובץ Cookie של פטור שצריך להעריך לא זמינים או לא תקינים בגלל אחת מהסיבות הבאות:

  • האסימון פגום ואי אפשר לפענח אותו.
  • הטוקן מכיל מאפיינים לא תקינים. לדוגמה, הטוקן נוצר באמצעות מפתח reCAPTCHA שלא תואם למפתחות reCAPTCHA שמשויכים לכלל.
  • התוקף של הטוקן פג.
שדה סוג תיאור
token.recaptcha_exemption.valid bool קובץ Cookie תקף של פטור מ-reCAPTCHA.

מאפיינים של טוקן פעולה

שדה סוג תיאור
token.recaptcha_action.score float הניקוד מטוקן פעולה של reCAPTCHA. הציון התקין נע בין 0.0 ל-1.0, כאשר 0.0 מציין שסביר מאוד שמדובר במשתמש לא לגיטימי, ו-1.0 מציין שסביר מאוד שמדובר במשתמש לגיטימי.
token.recaptcha_action.captcha_status string סטטוס ה-CAPTCHA מטוקן פעולה של reCAPTCHA. סטטוס תקין הוא NONE, PASS או FAIL, כאשר NONE מתייחס למצב שבו לא נדרש אתגר במהלך בדיקת reCAPTCHA, כך ששדה ה-CAPTCHA חסר בטוקן הפעולה.
token.recaptcha_action.action string שם הפעולה (עד 100 תווים) מ-reCAPTCHA action-token. שמות הפעולות
token.recaptcha_action.valid bool נוכחות של טוקן פעולה תקין של reCAPTCHA.

מאפיינים של טוקן לסשן

שדה סוג תיאור
token.recaptcha_session.score float הניקוד מאסימון סשן של reCAPTCHA. הציון התקין נע בין 0.0 ל-1.0, כאשר 0.0 מציין שסביר מאוד שמדובר במשתמש לא לגיטימי, ו-1.0 מציין שסביר מאוד שמדובר במשתמש לגיטימי.
token.recaptcha_session.valid bool נוכחות של טוקן תקף של סשן reCAPTCHA.

ביטויים לדוגמה

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

אישור או דחייה של גישה על סמך טווח כתובות IP ב-IPv4 או ב-IPv6

  • הביטוי הבא תואם לבקשות מטווח כתובות ה-IP‏ 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24')
    
  • הביטוי הבא תואם לבקשות מטווח כתובות ה-IP‏ 2001:db8::/32:

    inIpRange(origin.ip, '2001:db8::/32')
    

אישור או דחייה של גישה על סמך טווח כתובות IP מותאם אישית של לקוחות מאחורי שרת proxy במעלה הזרם

אם הגדרתם את האופרטור origin.user_ip, תוכלו להתאים על סמך ערכי הכותרת שציינתם בשדה advancedOptionsConfig.userIpRequestHeaders[].

  • הביטוי הבא תואם לבקשות שמקורן בטווח כתובות ה-IP‏ 192.0.2.0/24:

    inIpRange(origin.user_ip, '192.0.2.0/24')
    
  • הביטוי הבא תואם לבקשות שמקורן בטווח כתובות ה-IP‏ 2001:db8::/32:

    inIpRange(origin.user_ip, '2001:db8::/32')
    
  • הביטוי הבא תואם לבקשות שיש להן קובץ Cookie שמכיל את הערך 80=BLAH:

    has(request.headers['cookie']) && request.headers['cookie'].contains('80=BLAH')
    

התרת תנועה או דחייה של תנועה עם כותרת referer לא ריקה

  • הביטוי הבא תואם לבקשות עם כותרת referer לא ריקה:

    has(request.headers['referer']) && request.headers['referer'] != ""
    

אישור או דחייה של תנועה על סמך כותרת המארח

אפשר לאשר או לדחות תנועה על סמך הערך של הכותרת Host בבקשה.

  • הביטוי הבא תואם לבקשות לכתובת URL ספציפית באמצעות ==:

    request.headers['host'].lower() == 'test.example.com'
    
  • הביטוי הבא תואם לבקשות לכתובת URL ספציפית באמצעות endsWith:

    request.headers['host'].lower().endsWith('.example.com')
    
  • הביטוי הבא תואם לבקשות לכתובת URL ספציפית באמצעות contains:

    request.headers['host'].lower().contains('test.example.com')
    
  • הביטוי הבא תואם לבקשות למספר דומיינים באמצעות contains:

    request.headers['host'].lower().contains('test.example.com') || request.headers['host'].lower().contains('test22.example.com')
    
  • הביטוי הבא תואם לבקשות לדומיין ולתת-הדומיינים שלו באמצעות matches:

    request.headers['host'].matches('(?i:(sub\.)?test\.example\.com)')
    

אישור או דחייה של תנועה מאזור ספציפי

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

  • בכלל דחייה, משתמשים בביטוי הבא שתואם לבקשות מהאזור AU:

    origin.region_code == 'AU'
    

לחלופין, אם אפליקציית האינטרנט שלכם זמינה רק באזור AU, צריך לחסום בקשות מכל שאר האזורים.

  • בכלל דחייה, משתמשים בביטוי הבא, שתואם לבקשות מכל האזורים מלבד אזור AU:

    origin.region_code != 'AU'
    

קודי האזור מבוססים על קודי ISO 3166-1 alpha 2. לפעמים אזור מתאים למדינה, אבל זה לא תמיד המצב. לדוגמה, הקוד US כולל את כל המדינות בארצות הברית, מחוז אחד ושישה אזורים מרוחקים.

אישור או דחייה של תנועה ממספר מערכת אוטונומית (ASN) ספציפי

אם אתם רוצים לחסום את אפליקציית האינטרנט שלכם ללקוחות של מפעיל רשת ספציפי, אתם יכולים להשתמש במספר ה-ASN של מפעיל הרשת כדי לחסום אותה.

  • בכלל דחייה, משתמשים בביטוי הבא שתואם לבקשות מ-ASN ספציפי:

    origin.asn == 123
    

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

  • בכלל דחייה, משתמשים בביטוי הבא, שתואם לכל מפעילי הרשת האחרים מלבד זה שרוצים לאפשר:

    origin.asn != 123
    

כמה הבעות

כדי לכלול כמה תנאים בכלל אחד, משלבים כמה ביטויי משנה.

  • בדוגמה הבאה, בקשות מ-1.2.3.0/24 (למשל, מבודקי אלפא) באזור AU תואמות לביטוי הבא:

    origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
    
  • הביטוי הבא תואם לבקשות מ-1.2.3.4 שבהן סוכן משתמש מכיל את המחרוזת WordPress:

    inIpRange(origin.ip, '1.2.3.4/32') &&
    has(request.headers['user-agent']) && request.headers['user-agent'].contains('WordPress')
    

אישור או דחייה של תנועה עבור URI של בקשה שתואם לביטוי רגולרי

  • הביטוי הבא תואם לבקשות שמכילות את המחרוזת /example_path/ במזהה ה-URI:

    request.path.matches('/example_path/')
    
  • הביטוי הבא תואם לבקשות שכוללות את הערך Chrome בשדה הכותרת User-Agent:

    request.headers['user-agent'].matches('Chrome')
    
  • הביטוי הבא מציג התאמה לא תלוית-רישיות לכותרת User-Agent שמכילה את המחרוזת wordpress. הוא מתאים למחרוזות User-Agent:WordPress/605.1.15, User-Agent:wordPress ולוריאציות אחרות של wordpress:

    request.headers['user-agent'].matches('(?i:wordpress)')
    

התרת תנועה שמכילה ערך מפוענח ספציפי בקידוד base64 או דחיית תנועה כזו

  • הביטוי הבא תואם לבקשות עם ערך מפוענח ב-Base64 של myValue בכותרת user-id:

    has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
    

לאשר או לדחות תנועה שמכילה ערך מחרוזת באורך מסוים

  • הביטוי הבא תואם לבקשות שכתובת ה-URL שלהן ארוכה מ-10 תווים:

    size(request.path) > 10
    
  • הביטוי הבא תואם לבקשות עם כותרת x-data באורך של 1,024 תווים או יותר:

    size(request.headers['x-data']) >= 1024
    

התרת תנועה או דחייה של תנועה עם content-length בגוף ה-HTTP

  • הביטוי הבא תואם לבקשות שכוללות אפס content-length בגוף ה-HTTP:

    int(request.headers["content-length"]) == 0
    

אישור או דחייה של תנועה שמכילה ערך מקודד ספציפי של כתובת URL

  • הביטוי הבא תואם לבקשות עם ערך של קובץ Cookie שמכיל %3c:

    has(request.headers['cookie']) && request.headers['cookie'].urlDecode().contains('<')
    

אישור או דחייה של תנועה שמכילה ערך מקודד ספציפי של כתובת URL של מחרוזת Unicode

  • הביטוי הבא תואם לבקשות עם ערך קובץ Cookie ששווה ל-Match%2BValue או ל-Match%u002BValue:

    has(request.headers['cookie']) && request.headers['cookie'].urlDecodeUni() == 'Match+Value'
    

אישור או דחייה של תנועה שמכילה מחרוזת Unicode ספציפית של טקסט UTF-8

  • הביטוי הבא תואם לבקשות עם ערך קובץ Cookie ששווה ל-¬:

    has(request.headers['cookie']) && request.headers['cookie'].utf8ToUnicode() == '%u00ac'
    

התרת תנועה או דחייה שלה על סמך טביעת אצבע מוכרת של JA4

  • הביטוי הבא תואם לבקשות עם טביעת אצבע של JA4 ששווה ל-t13d1516h2_8daaf6152771_b186095e22b6:

    origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
    

התרת תנועה או דחיית תנועה על סמך רשימה של טביעות אצבע של JA4

  • הביטוי הבא תואם לבקשות עם טביעת אצבע JA4 ששווה לאחת מטביעות האצבע הבאות של JA4:

    • t00d0000h0_000000000000_000000000000
    • t13d1516h2_8daaf6152771_b186095e22b6
    origin.tls_ja4_fingerprint == 't00d0000h0_000000000000_000000000000' || origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
    

אישור או דחייה של תנועת גולשים על סמך תוכן גוף הבקשה

  • הביטוי הבא תואם לבקשות POST שמכילות את המחרוזת malicious-value בגוף הבקשה:

    request.method == 'POST' && request.body.contains('malicious-value')
    
  • הביטוי הבא תואם לבקשות שמתחילות ב-:

    request.body.startsWith('')
    
  • הביטוי הבא תואם לבקשות שבהן הגוף תואם לביטוי הרגולרי \w+@\w+.com:

    request.body.matches('\w+@\w+.com')
    

אישור או דחייה של תנועה על סמך פרמטרים של בקשות

  • הביטוי הבא תואם לבקשות שלא מכילות פרמטר בשם category:

    !has(request.params.category)
    
  • הביטוי הבא מתאים לבקשות שבהן הפרמטר category הוא electronics:

    request.params.category == 'electronics'
    
  • הביטוי הבא תואם לבקשות שבהן כל ערכי הפרמטרים לא ריקים:

    request.params.all(k, request.params[k] != '')
    
  • הביטוי הבא תואם לבקשות שבהן פרמטר כלשהו מכיל את המחרוזת admin:

    request.params.exists(k, request.params[k].contains('admin'))
    
  • הביטוי הבא מתאים לבקשות שבהן בדיוק שם פרמטר אחד מכיל את admin:

    request.params.exists_one(k, k.contains('admin'))
    
  • הביטוי הבא תואם לבקשות שבהן לפחות שם פרמטר אחד מכיל את id:

    size(request.params.filter(k, k.contains('id'))) > 0
    
  • הביטוי הבא תואם לבקשות שבהן ערכי הפרמטרים כוללים את המחרוזת admin:

    request.params.map(k, request.params[k]).contains('admin')
    

אישור או דחייה של תנועה על סמך נתונים מובְנים בגוף הבקשה

  • הביטוי הבא תואם לבקשות שבהן השדה password בגוף בקשת JSON מכיל את הערך 123:

    has(request.params.password) && request.params.password.contains('123')
    
  • הביטוי הבא תואם לבקשות שבהן השדה city בנתוני הטופס הוא NewYork:

    has(request.params.city) && request.params.city == 'NewYork'
    
  • הביטוי הבא תואם לבקשות שבהן השדה newsletter המקונן הוא true:

    has(request.params.preferences) && has(request.params.preferences.newsletter) && request.params.preferences.newsletter == true
    
  • הביטוי הבא תואם לבקשות שבהן השדה name של הרכיב הראשון במערך friends הוא johndoe:

    request.params['friends'][0]['name'] == 'johndoe'
    

כללי WAF שהוגדרו מראש

כללי WAF שהוגדרו מראש משתמשים בחתימות סטטיות שהוגדרו מראש, בביטויים רגולריים או בשניהם כדי להתאים לגוף של בקשת HTTP, לכותרות של בקשת HTTP ולפרמטרים של שאילתה. כללי ה-WAF המוגדרים מראש מבוססים על OWASP Core Rule Set 4.22. ב-Cloud Armor יש כמה כללי WAF מוגדרים מראש. רשימה מלאה של כללי WAF שהוגדרו מראש זמינה במאמר סקירה כללית של כללי WAF שהוגדרו מראש ב-Cloud Armor.

כדי לראות רשימה של כל כללי ה-WAF שהוגדרו מראש, אפשר לעיין במאמר בנושא רשימת כללי WAF שהוגדרו מראש.

מידע נוסף על כללי WAF שהוגדרו מראש זמין בתרחיש לדוגמה צמצום התקפות בשכבת האפליקציה באמצעות כללי WAF שהוגדרו מראש.

שמות של כללי WAF שהוגדרו מראש

השמות של כללי WAF שהוגדרו מראש הם בפורמט --. קטגוריית המתקפה מציינת את סוג המתקפות שרוצים להתגונן מפניהן, כמו xss (פרצת אבטחה XSS‏ (cross-site scripting)) או sqli (הזרקת SQL).

שדות הגרסה הנתמכים הם stable ו-canary. תוספות ושינויים בכללים מתפרסמים קודם בגרסה canary. כאשר תוספות ושינויים נחשבים בטוחים ויציבים, הם מקודמים לגרסה stable.

מזהים של חברים בכללי WAF שהוגדרו מראש

כלל WAF שהוגדר מראש מכיל כמה ביטויים, שלכל אחד מהם יש חתימה משלו. לדוגמה, כלל ה-WAF שהוגדר מראש xss-v422-stable כולל ביטוי בשם owasp-crs-v042200-id941100-xss, שמתאים למזהה הכלל id941100 בגרסה 4.22. אתם יכולים להשתמש בחתימות כדי להחריג ביטויים ספציפיים, וכך למנוע את השימוש בהם. זה שימושי אם ביטוי מסוים מפעיל באופן עקבי תוצאה חיובית שגויה. מידע נוסף זמין במאמר בנושא תוצאות חיוביות שגויות.

מידע על קבוצת כללי הליבה ועל כוונון ברמות רגישות שונות זמין במאמר כוונון כללי WAF ב-Cloud Armor.

אופרטור לכללי WAF שהוגדרו מראש

ביטויים תיאור
evaluatePreconfiguredWaf(string, MAP) הפונקציה מחזירה את הערך true אם אחת מחתימות ה-WAF בתוך קבוצת כללי ה-WAF שצוינה מחזירה את הערך true. הארגומנט הראשון הוא השם של קבוצת הכללים של ה-WAF, למשל xss-v422-stable. הארגומנט השני (אופציונלי) הוא מפה שבה המפתח הוא מחרוזת והערך הוא הקלדה דינמית בהתאם למפתח. המטרה של הארגומנט הזה היא לכוונן את החתימות של ה-WAF שמוערכות. המפתחות הקבילים כוללים את:
  • ‫sensitivity: הערך הזה תואם לרמת הפרנויה של OWASP Core Rule Set, שכוללת 4 רמות, מ-1 עד 4. הערך שלו הוא מספר שלם בטווח התקף של 0 עד 4. שימו לב שהערך 0 שמור כערך תקין כשמשתמשים בו בשילוב עם opt_in_rule_ids (כפי שמתואר בהמשך). כשמציינים רמת רגישות של x‏ (x >= 1), כל החתימות המשויכות של WAF עם ערך רגישות מ-1 עד x מוערכות. אם לא מציינים ערך, המערכת משתמשת בערך הרגישות 4.
  • ‫opt_out_rule_ids: חתימות של WAF (מיוצגות על ידי מזהי כללים) שרוצים להחריג מההערכה, כאשר קבוצת הבסיס נקבעת על ידי ערך הרגישות. הערך שלו הוא רשימה של מחרוזות. המספר המקסימלי של מזהי כללים הוא 128.
  • ‫opt_in_rule_ids: חתימות של WAF (מיוצגות על ידי מזהי כללים) שצריך להפעיל כדי לבצע הערכה, כאשר קבוצת הבסיס ריקה. הערך שלו הוא רשימה של מחרוזות. המספר המקסימלי של מזהי כללים הוא 128. כשמשתמשים במאפיין הזה, צריך לציין sensitivity עם הערך 0.

המפתחות opt_out_rule_ids ו-opt_in_rule_ids הם ייחודיים. אתם יכולים להשתמש ב-opt_in_rule_ids אם אתם רוצים לבדוק ולבחור באופן ידני חתימות WAF חדשות שנוספו מאוחר יותר לקבוצת כללים קיימת.

evaluateManagedRules(string, MAP) הפונקציה מחזירה את הערך true אם אחת מהחתימות בתוך הכללים המנוהלים שצוינו מחזירה את הערך true. הארגומנט הראשון הוא השם המוגדר במלואו של הקטגוריה, כמו google:xss:stable או google:sqli:canary. הארגומנט השני (אופציונלי) הוא מיפוי שבו המפתח הוא מחרוזת והערך הוא הקלדה דינמית בהתאם למפתח. המפתחות הקבילים כוללים את האפשרויות הבאות:
  • ‫opt_in_rule_ids: רשימה של מזהי כללים מקבוצת הכללים המתאימה, שהם הכללים היחידים שנבדקים. לדוגמה, evaluateManagedRules('google:xss:canary', {'opt_in_rule_ids': ['google-xss-8057544707029182464']}).
  • ‫opt_out_rule_ids: רשימה של מזהי כללים מקבוצת הכללים התואמת שמוחרגים מההערכה. לדוגמה, evaluateManagedRules('google:xss:canary', {'opt_out_rule_ids': ['google-xss-8057544707029182464']}).
evaluatePreconfiguredWaf(string, LIST)

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

הארגומנט הראשון הוא השם של כלל ה-WAF שהוגדר מראש, למשל xss-stable. הארגומנט השני (אופציונלי) הוא רשימה של מזהים מופרדים בפסיקים שצריך להחריג מההערכה. רשימת ההחרגות שימושית כשחבר מסוים בכלל WAF שהוגדר מראש מפעיל תוצאה חיובית שגויה.

דוגמאות לכללי WAF שהוגדרו מראש

  • הביטוי הבא משתמש בכלל WAF שהוגדר מראש xss-v422-stable כדי לצמצם את הסיכון להתקפות XSS:

    evaluatePreconfiguredWaf('xss-v422-stable')
    
  • הביטוי הבא משתמש בכל הביטויים מכלל ה-WAF שהוגדר מראש xss-v422-stable מלבד מזהי החברים 941100 ו-941110:

    evaluatePreconfiguredWaf('xss-v422-stable', {'opt_out_rule_ids': ['owasp-crs-v042200-id941100-xss',
    'owasp-crs-v042200-id941110-xss']})
    
  • הביטוי הבא משתמש בכלל WAF שהוגדר מראש כדי לצמצם את ההשפעה של מתקפות SQLi מטווח כתובות ה-IP‏ 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredWaf('sqli-v422-stable')
    
  • הביטוי הבא משתמש בכלל WAF שהוגדר מראש xss-v422-stable כדי לצמצם את הסיכון להתקפות XSS בבקשות אל example.com, לא כולל נתיבים שמתחילים ב-/login/api/:

    request.headers['host'].lower() == 'example.com' && !request.path.startswith('/login/api/') && evaluatePreconfiguredWaf('xss-v422-stable')
    

דוגמאות לכללים מנוהלים

  • הביטוי הבא משתמש בכללי הזרקת SQL (sqli) יציבים ומנוהלים כדי למנוע מתקפות SQLi:

    evaluateManagedRules('google:sqli:stable')
    
  • הביטוי הבא משתמש בכללי xss המנוהלים היציבים רק אם בבקשה מופיע המארח example.com:

    request.headers['host'].lower() == 'example.com' && evaluateManagedRules('google:xss:stable')
    

אופרטורים אחרים

ביטויים תיאור
evaluateThreatIntelligence(string)
evaluateThreatIntelligence(string, LIST)
evaluateThreatIntelligence(string, string, LIST)

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

הארגומנט הראשון הוא השם של הפיד של Google Threat Intelligence, כמו iplist-known-malicious-ips. אם הארגומנט השני הוא מחרוזת (אופציונלי), הוא קובע מאיפה כתובת ה-IP מחולצת, והוא יכול להיות origin.ip,‏ origin.user_ip או שם של כותרת ספציפית. אם הארגומנט השני או השלישי (אופציונלי) הוא רשימה של מחרוזות שמופרדות באמצעות פסיקים, כאשר כל מחרוזת היא כתובת IP או טווח CIDR, הכתובות או הטווח האלה יוחרגו מההערכה. רשימת ההחרגות שימושית אם פיד מכיל כתובת IP שמפעילה תוצאה חיובית שקרית.

evaluateAddressGroup(string, string)
evaluateAddressGroup(string, string, LIST)

evaluateOrganizationAddressGroup(string, string)
evaluateOrganizationAddressGroup(string, string, LIST)

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

הארגומנט הראשון הוא שם קבוצת הכתובות. הארגומנט השני קובע מאיפה כתובת ה-IP מחולצת, והוא יכול להיות origin.ip, origin.user_ip או שם של כותרת ספציפית. הארגומנט השלישי (אופציונלי) הוא רשימה מופרדת בפסיקים של מחרוזות, כאשר כל מחרוזת היא כתובת IP או טווח CIDR, שיוחרגו מההערכה. רשימת ההחרגות שימושית אם קבוצת כתובות מכילה כתובת IP מסוימת שגורמת לתוצאה חיובית שקרית.

evaluateAdaptiveProtection(string)

הפונקציה מחזירה את הערך true אם הבקשה תואמת לחתימת המתקפה שנוצרה על ידי התכונה 'הגנה דינמית' ב-Google Cloud Armor.

הארגומנט הוא המזהה של התראה ספציפית שנוצרה על ידי הגנה דינמית אחרי זיהוי של מתקפה.

evaluateAdaptiveProtectionAutoDeploy()

הפונקציה מחזירה את הערך true אם הבקשה מגיעה מכתובת IP של תוקף משמעותי שתואמת לחתימת התקפה של התקפה מתמשכת שזוהתה על ידי ההגנה הדינמית.

דוגמאות

  • הביטוי הבא משווה את הבקשה הנכנסת לפיד של Google Threat Intelligence iplist-known-malicious-ips כדי להגן מפני רשימת כתובות ה-IP הזדוניות הידועות:

    evaluateThreatIntelligence('iplist-known-malicious-ips')
    
  • הביטוי הבא מתאים לבקשה הנכנסת מול פיד Google Threat Intelligence‏ iplist-known-malicious-ips להגנה מפני רשימת כתובות ה-IP הזדוניות הידועות, למעט כתובות ה-IP ב-203.0.113.0/24:

    evaluateThreatIntelligence('iplist-known-malicious-ips', ['203.0.113.0/24'])
    
  • הביטוי הבא מתאים לכותרת הבקשה המותאמת אישית של כתובת ה-IP של המשתמש לקבוצת הכתובות שנקראת my-own-list-of-bad-ips:

    evaluateAddressGroup('my-own-list-of-bad-ips', origin.user_ip)
    

המאמרים הבאים