עוגיות VS. טוקנים

עוגיות VS. טוקנים. מי לוקח? יש הבדל? רגע, מה עם הסשן עצמו? 🤔 זהויות היו ונותרו שטח תקיפה בעייתי. 

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

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

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

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

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

עוגיות VS. טוקנים

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

קובצי עוגיות הם חלקי (Chunks) נתונים שנוצרו על ידי השרת (Server) ונשלחו ליוזר (Client) למטרות תקשורת ואימות. לעומת זאת, טוקנים, מתייחסים בדרך כלל לטוקן אינטרנטי סטייל JWTs, והם אישורים חתומים המקודדים למחרוזת ארוכה של תווים שנוצרו על ידי השרת. ההבדל העיקרי בין טוקנים לעוגיות הוא, טוקנים הם stateless, ועוגיות הם stateful!

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

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

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

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

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

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

אופן האימות יכול להשתנות בכל סביבה, וכן תלוי בסביבת Frontend וכן Backend ובפרט בצורה שבה מנגישים API. 

אימות מבוסס עוגיות

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

בואו נפרק את התהליך הזה למספר חלקים.

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

השרת מאמת את הקרדס ויוצר סשן 
 
 

השרת מגיב עם עוגיה לדפדפן על ידי הכללתו בפרמטר Set-Cookie

הדפדפן מאחסן את העוגיה מקומית ושולח אותו עם הבקשות הבאות

בעת התנתקות המשתמש, המערכת תמחק את הסשן 

נקודות בתהליך

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

יתרונות בעוגיות

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

מניפולציות – אפשר להגביל את הגישה בצד הבראוסר (לקוח) על ידי הגדרת פרמטר HTTP ONLY (או פלאג), וזה יכול להקטין את הסבירות להתקפות XSS על היישום. רוב התקפות XSS כרוכות בשימוש בקוד JS זדוני.

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

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

חסרונות בעוגיות

זיוף עוגיות – תקיפות XSRF או CSRF הן למעשה תקיפות חוצות אתרים שמטתרן לזייף עוגיות. התקפות CSRF אפשריות במצבים של cookie based session. במצב כזה, התכונה של samesite מאפשרת להחליט האם צריך לשלוח עוגיות לאפליקציות של צד שלישי באמצעות הגדרות Strict או Lax. הגדרה קפדנית יכולה למנוע התקפות CSRF, אך היא יכולה גם לתרום לחוויית דפדפן גרועה ביותר עבור המשתמש. 

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

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

נקודות נוספות

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

אימות מבוסס טוקנים

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

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

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

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

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

לאחר מכן, מאחסן את הטוקן בדפדפן ומוסיף אותו לבקשות הבאות באמצעות JS

יתרונות

טוקנים ובפרט JWT הם stateless ולכן השרת אינו צריך לנהל רישום של הטוקן. כל טוקן הוא עצמאי, ומחזיק את המידע הדרוש לאימות וזיהוי בשרת.
– קלות – JWT קלים לשימוש. האופי שלהם מסייע באימות ללא בדיקות אל מול מסדי נתונים. זה הופך את JWT למתאימים יותר לשימוש מול API, מכיוון ששירות API אינו צריך לעקוב אחר הפעלות משתמשים.
– יכולות חוצות פלטפורמות – בגלל האופי שלהם (stateless), ניתן ליישם טוקנים בצורה חלקה בפלטפורמות ניידות וביישומי אינטרנט של הדברים (IoT), במיוחד בהשוואה לעוגיות.
– אפשרויות אחסון – ניתן לאחסן טוקנים במספר דרכים בדפדפנים או ביישומים חזיתיים.

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

חסרונות

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

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

Stale טוקן – המידע בתוך JWT מייצג תמונת מצב בזמן שבו הטוקן נוצר במקור. ייתכן שלמשתמש המשויך יש כעת רמות גישה שונות או שהוא הוסר מהמערכת לחלוטין.

נקודות נוספות 

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

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

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

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

קצת מהשטח

ישנם דרכים רבות להסניף את התעבורה והבקשות של עוגיות וטוקנים מול יישומי אינטרנט וספקי זהויות. כלים יש למכביר, ולכן נתמקד בכלי מוכר וידוע – Fiddler. הבדיקה שנעשה היא מול יוזר שמבצע אימות מול Azure AD באמצעות MFA. 

כאשר יוזר צריך להזדהות מול שירות Azure או M365 הוא עובד מול רכיב זהויות לצורך אימות – במקרה הזה מול Azure AD. כאשר עובדים מול Azure AD ניתן לבצע אימות שמתבסס על STS או Managed – בשניהם זהה.

כאשר היוזר עובד מול רכיב STS שיאמת אותו ויאפשר לו לפתוח סשן, וכן להעביר אותו לשירות הנדרש (Azure/M365 או צד שלישי). במצב כזה יונפק ליוזר טוקן SAML ע"י רכיב האימות (SAS/STS/Managed). לאחר מכן יחל תהליך אימות מול אימות רב גורמי (MFA), ומשם יתחיל גם טעינת קובץ עוגיות עם כל הפרמטרים הנדרשים. 

מאפיינים בתהליך הלוגין והאימות:

– ביצוע פעולת POST 
– ביצוע פעולת GET
– טעינת סשן וערכים (Set-Cookie)

בתהליך האימות עם מעורבות MFA מתרחשים מספר פעולות

– בתהליך הלוגין ולאחר הזנת קרדס מוגדר ערך SANeeded והכתובת מעוברת אל כתובת שמסתיימת ב StrongAuthCheck.srf.

– לאחר מכן התהליך ממשיך אל כתובת שמתסיימת ב BeginAuth – במצב כזה נעשה הטריגר של MFA

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

בצקרה הזה, לאחר שהמכשיר הנייד נבחר ואומת, התשובה עבור השאילתה הבאה עבור EndAuth תהיה תוצאה של הצלחה. בנוסף, המשתמש השלים את אימות Mulitifactor. כמו כן, העוגייה Set-Cookie : SANeeded מוגדרת בתגובה, ולכן תועבר לנקודת הקצה : login.srf בכדי להשלים את האימות.

ערכים נוספים 

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

– כל בקשה בתהליך נחלקת לשניים: Request + Response
– ערכים שצריך לנתח הם Headers + Cookie + Json + Set-Cookie
– ערכים נבחרים: AuthMethodId + Cookie + Entity + FlowToken + SeesionId + Result

קישורים נבחרים

Pass the Cloud with a Cookie (misconfig.io)

How to use Fiddler trace logs for MFA in Microsoft 365 and Azure AD – Office 365 | Microsoft Learn



:קטגוריותAzure AD, Microsoft Entra, Security

תגים: , , , , , ,

תגובה אחת

  1. מאמר מצויין אלי היקר

השאר תגובה

error: Content is protected !!
%d בלוגרים אהבו את זה: