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

שתי טענות, ורק אחת מהן מתחילה אצל המבקר

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

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

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

שירות הוצאות מעובד, ושתי הדרכים שבהן הוא מפסיד

קחו שירות הוצאות: שער ציבורי בכתובת 10.60.4.10 מאמת עובדים ומעביר בקשות מאושרות למאזין יישום בפורט 8443, והיישום הזה מגיע למאזין PostgreSQL אחד בכתובת 10.60.4.20:5432 בתפקיד expenses_app. העובדים אינם אמורים לקבל גישה פנימית כללית. בפעולה רגילה העיצוב אכן מספק כניסה ספציפית ליישום בלי לפרסם את מאזין מסד הנתונים בשום מקום. הכתובות חשובות, משום שכל בדיקה בהמשך המאמר הזה נוקבת בהן.

כעת הסירו את השער מהקבוצה המהימנה. לאילו יעדים יכול 10.60.4.10 להגיע לאחר שהתהליך שלו שייך לתוקף? מסנן ה-URL שהגביל מבקרים אינו אומר דבר על חיבור שמארח השער פותח לכיוון תת-הרשת של מסד הנתונים.

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

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

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

ComponentAuthority it actually holdsCheck that proves the denialOwner of the check
Identity providerIssues assertions and session cookies, and holds no network path of its ownA request to the application URL without a session is redirected to the login pageIdentity team
Public gateway hostTCP reachability to whatever its routing table and egress rules permitAn egress rule drops 10.60.4.20:5432 and the probe reports the port filteredNetwork platform team
Application roleSQL privileges granted to expenses_app inside the expenses databaseA privilege query shows no ownership or create right on any other schemaApplication team
Database listenerAccepts connections only from the source ranges named in its host-based rulesA connection from an unlisted address is refused before authenticationDatabase administrator
Management pathAdministrative access reserved for patching, monitoring and recoveryA staff workstation cannot reach the administrative port or jump through itPlatform owner

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

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

מנו מה השער יכול להגיע אליו במקום להצהיר על כך

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

ip route get 10.60.4.20
nc -zv 10.60.4.20 5432
sudo nft list chain inet filter output

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

חזרו על המנייה ממארח היישום. משם צד מסד הנתונים הוא שאילתה אחת שמופעלת בתפקיד היישום:

psql -h 10.60.4.20 -U expenses_app -d expenses -c 'select rolname, rolsuper, rolcreatedb from pg_roles'

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

תעדו את הסירובים, ואז תארכו את הסקירה

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

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

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

מאמרים קשורים