למה יכולה עדיין להגיע שער אינטרנט שנפרץ?
שער אינטרנט מגביל מה מבקר פותח, לא למה מארח שנפרץ יכול להתחבר. שתי סקירות, טבלת סמכויות ופקודות למדידת הטווח.
נניח שמארח השער נפרץ בזמן שהתעודה שלו עדיין תקפה. כל כלל שקבע אילו דפים מבקר רשאי לבקש נשאר בתוקף, ואף אחד מהכללים האלה אינו מגביל את החיבור שהתוקף פותח כעת מאותו מארח לכיוון תת-הרשת של מסד הנתונים. הפער הזה הוא הסיבה לכך שנקודת כניסה לאינטרנט בלבד אינה אותה טענה כמו רשת מחולקת. שתי הטענות דורשות סקירות נפרדות, מנקודות מוצא שונות, לפני שאפשר להציג אף אחת מהן ביושר.
שתי טענות, ורק אחת מהן מתחילה אצל המבקר
הטענה הראשונה עוסקת באדם: מבקר עם דפדפן והפעלה תקפה יכול לפתוח יישום אחד ושום דבר אחר. נקודת כניסה לאינטרנט בלבד עונה על הטענה הזו היטב, משום שהמבקר מקבל דף ולא מסלול. התשובה הזו שווה שיהיה לה מקום, והיא גם הטענה היחידה שרוב התרשימים מתעדים.
הטענה השנייה עוסקת ברכיב: מניחים שהשער, או תהליך היישום שמאחוריו, נמצא בשליטתו של מישהו אחר. מההנחה הזו משתנה השאלה מיהיהן כתובות ה-URL המותרות לאילו יעדים וזהויות התהליך עדיין יכול להגיע.
לשתי הטענות בעלים שונים, הן מפיקות ראיות שונות ונכשלות באופן בלתי תלוי. צוות זהות יכול להדגים את הראשונה בבדיקת הפעלה; השנייה דורשת מדיניות רשת, סקירת חשבון שירות ובקרות מארח. עיצוב שמתעד רק את חצי המבקר נראה שלם בשקופית סקירה ודק בזמן אירוע, משום שהבקרות שחשובות אחרי פריצה מעולם לא היו בהיקף. סמנו איזו טענה כל בקרה תומכת, אחרת כלל שער אחד יזוכה לשניהן.
שירות הוצאות מעובד, ושתי הדרכים שבהן הוא מפסיד
קחו שירות הוצאות: שער ציבורי בכתובת 10.60.4.10 מאמת עובדים ומעביר בקשות מאושרות למאזין יישום בפורט 8443, והיישום הזה מגיע למאזין PostgreSQL אחד בכתובת 10.60.4.20:5432 בתפקיד expenses_app. העובדים אינם אמורים לקבל גישה פנימית כללית. בפעולה רגילה העיצוב אכן מספק כניסה ספציפית ליישום בלי לפרסם את מאזין מסד הנתונים בשום מקום. הכתובות חשובות, משום שכל בדיקה בהמשך המאמר הזה נוקבת בהן.
כעת הסירו את השער מהקבוצה המהימנה. לאילו יעדים יכול 10.60.4.10 להגיע לאחר שהתהליך שלו שייך לתוקף? מסנן ה-URL שהגביל מבקרים אינו אומר דבר על חיבור שמארח השער פותח לכיוון תת-הרשת של מסד הנתונים.
הסירו במקום זאת את תהליך היישום, והסמכות משנה צורה: התפקיד expenses_app, השירותים שהשרת הזה יכול להגיע אליהם והקבצים שהחשבון הזה יכול לקרוא. בשני המקרים הדלת הקדמית יכולה להישאר אינטרנט בלבד בעוד גבול ה-backend חסר. לכן התווית על הדלת הקדמית אינה תשובה לאף אחת משתי השאלות.
מפו את הסמכות שכל צד מחזיק בפועל
חוזה שנכתב כהרשאות מכוונות נוטה לחזור על העיצוב בפניכם. כתבו אותו כסמכות מוחזקת, הבדיקה שמפריכה את העודף והבעלים של אותה בדיקה, וכל שורה נעשית ניתנת לבדיקה. הטבלה הזו היא הצעה לדוגמה שלמעלה, לא טענת מוצר:
| Component | Authority it actually holds | Check that proves the denial | Owner of the check |
|---|---|---|---|
| Identity provider | Issues assertions and session cookies, and holds no network path of its own | A request to the application URL without a session is redirected to the login page | Identity team |
| Public gateway host | TCP reachability to whatever its routing table and egress rules permit | An egress rule drops 10.60.4.20:5432 and the probe reports the port filtered | Network platform team |
| Application role | SQL privileges granted to expenses_app inside the expenses database | A privilege query shows no ownership or create right on any other schema | Application team |
| Database listener | Accepts connections only from the source ranges named in its host-based rules | A connection from an unlisted address is refused before authentication | Database administrator |
| Management path | Administrative access reserved for patching, monitoring and recovery | A staff workstation cannot reach the administrative port or jump through it | Platform 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 ורוב התרשימים משמיטים.
תארכו את הסקירה ונקבו בשם הבעלים שלה. הריצו שוב את המנייה ואת שאילתת ההרשאות לאחר כל שינוי בתמונת השער, בטבלת הניתוב או בתפקיד היישום.