לדלג לתוכן

הרעלת מטמון מוסברת - Cache Poisoning, איך בעיה קטנה הופכת לאסון גדול

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

קודם, איך מטמון בכלל עובד

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

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

אז איפה בדיוק נכנס התוקף

וכאן מתחיל הכיף. כותרות שמשפיעות על התוכן של הדף אבל לא נכנסות למפתח המטמון נקראות קלט לא ממופתח - unkeyed input. דוגמה קלאסית היא הכותרת X-Forwarded-Host, שהרבה אפליקציות משתמשות בה כדי לבנות קישורים בעמוד, למשל לינק "לאיפוס סיסמה" שמפנה בחזרה לדומיין של האתר.

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

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

למה זה כל כך יותר גרוע ממה שזה נשמע

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

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

איך מוצאים חולשות כאלה בפועל

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

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

הצטרפו לקהילה בדיסקורד

לסיכום

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