Thursday, December 30, 2010

CSRF



CSRF

תקפה באינטרנט שאוהבים לדבר עליה ולהזכיר אותה והיא סוג של להיט בשנים האחרונות בשיחות על Web Application Security.

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

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


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

אפשר לקרוא חומר על ההתקפה בוויקיפידה. לארגון OWASP שמפרסם מידע על Web Application Security ומפרסם על פתרונות זמינים לבעיות יש עמוד שמסביר על CSRF הדף מכיל גם קישורים עם עוד מידע מעמיק.

בצד השרת הנסיונות למנוע את ההתקפה היא באמצעות HTTP Headers כגון, Referer (שגיאת הכתיב היא במקור), Origin או הלהיט האחרון, X-Requested-With.

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

דרך קלה לטפל בכך בצד השרת (בד"כ על ידי שכבה או שרות שמולבש בין הגשת דפי האינטרנט לבין הלקוח, למשל על ידי Apache באחד ממודולי ה-Mod שלו או למשל על ידי Application Delivery Controller, כמו למשל F5 BIGIP שיש לו גם Web Application Firewall אינטגרטיבי, ה-ASM) היא להחליף את כל הקישורים בעמוד. החלפת הקישור כולו היא דוגמה לשיטה של ההצפנה והחלפה שמוסיפה את אותה פיסת מידע אקראית (לכאורה) היא דוגמה אחרת, שנפוצה יותר. בעייתיות של גישה זו היא מתי מבצעים את ההתערבות בקישורים ובכתובות. אם מדובר בקישורים סטטיים ב-HTML אז אין בעייה -- אבל ישנן כתובות שנוצרות באופן דינאמי בצד הלקוח ואז האופן להחליף אותן כראוי היא או במקור (זה דורש תמיכה ושיתוף פעולה עם המפתחים של האתר, זה לא קורה בדרך כלל -- ) או בדיעבד באופן דינאמי בצד הלקוח על ידי JavaScript או טכנולוגיית client side אחרת (למשל Flash).

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

הדרך להצליח בדיעבד ורק בצד הלקוח לשנות את הכתובת (על ידי הוספת אותו חלק מידע משתנה כאשר ניגשים לשרת) כאשר מדובר ב-Ajax היא לחטוף את הגישה. למה הכוונה? הכוונה היא להתחבר למודל האובייקטים ולהתערב בשרשרת הקריאות למתודות שמבצעות את הפעולות של Ajax כך שיהיה אפשרי להריץ קוד כאשר נוצרת בקשת Ajax: הקוד ישנה את הכתובת לפי הצורך. לפעמים גם אין דיי בכך ורוצים גם לחטוף את ה-Ajax Response ולבדוק אותו ולהכניס בו שינויים לפני שהאפליקציה בצד הלקוח משתמשת בו. מנסיוני האישי בפיתוח טכנולוגיות client side ב-F5 הנושא אינו פשוט כלל לפתרון כללי ובפרט קשה כאשר מדובר בתמיכה רחבה בדפדפנים מכל היצרנים, מכל הסוגים ומגרסאות שונות. קל וחומר כאשר קוד ה-JavaScript שמורץ גם הוא בא בטעמים שוניים ובשנים האחרונות גם בא בשימוש ב-JavaScript Frameworks שונים. גישה מקובלת לחטיפת תהליך של בקשת Ajax מובא להלן:
אפשר לקרוא את הקוד המלא (וללמוד כמה דברים) של הפתרון של OWASP בקישור.


XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
this.url = url;

this._open.apply(this, arguments);
}


XMLHttpRequest.prototype._send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(data) {
if(this.onsend != null) {
this.onsend.apply(this, arguments);
}
this._send.apply(this, arguments);
}


הכלי של OWASP משתמש ב X-Requested-With כדי להכריע האם בקשה מגיעה לשרת מ-Ajax או שלא. סיבה טובה לכך היא הקשר ההדוק ל-Same Origin Policy. לא ניתן לזייף ב-JavaScript בקשה בשימוש ב-XMLHttpRequest למתחם מסויים כך שתראה כאילו באה ממתחם אחר.

No comments:

Post a Comment