מהו JWT והאם מאובטח

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

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

המאמר הנוכחי מתמקד בתקן של JWT והקדמה לקראת המציאות בשטח ואפשרויות ניצול מול Azure AD.

מהו JWT

JSON Web Token או בקצרה JWT הוא תקן מבוסס JSON ליצירת מפתח גישה (Access Token) המשמש לאימות של דרישות/טענות, כמו, שם משתמש, הרשאות וסיסמה. לדוגמה, שירות ענני יכול ליצור מפתח הטוען "בוצעה כניסה כמנהל מערכת" ולספק את המפתח לדורש (יוזר, אפליקציה, Client).

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

המפתחות תוכננו להיות קצרים, בטוחים להעברה על גבי URL, ושמישים במיוחד בדפדפני אינטרנט בהקשר של SSO עם שימוש במספר רב של מערכות באמצעות מפתח יחיד. טענות JWT משמשות באופן טיפוסי כדי להעביר את הזהות של משתמשים מאומתים בין ספק זהויות (identity provider) לבין המקבל (service provider) או כל סוג אחר של טענות שמתקבלות מתוך בקשות כלשהן של JWT. 

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

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

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

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

Online JWT Builder

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

Online JWT Builder

הכותרת מורכבת בדרך כלל משני חלקים: סוג הטוקן, שהוא JWT, ואלגוריתם החתימה שבו נעשה שימוש, כגון HMAC SHA256 או RSA.

לאחר מכן, JSON מקודד Base64Url כדי ליצור את החלק הראשון של JWT.

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

טענות ציבוריות מוגדרות על ידי אלה המשתמשים כ JWT ובכדי למנוע התנגשויות הם צריכים להיות מוגדרים ברישום טוקן JSON או להיות מוגדרים ברמת URI המכיל מרחב שמות עמיד להתנגשות.

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

הפיילואד מקודד לאחר מכן כ Base64Url כדי ליצור את החלק השני של הטוקן JSON.

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

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

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

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

אימות טוקן JSON

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

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

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

שימו לב, במידה ושולחים טוקנים JWT דרך כותרות HTTP, עליך לנסות למנוע מהם להיות גדולים מדי. שרתים מסוימים אינם מקבלים כותרת שהיא מעל גודל של 8KB. לכן, אם מנסים להכניס יותר מידי ערכים בטוקן JWT, למשל על ידי הכללת כל הרשאות המשתמש, ייתכן שתזדקק לפתרון חלופי, פתרון שמבוסס על Grained Authorization.

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

אם כך, מדוע עלינו להשתמש בטוקן JSON? בואו נדבר על היתרונות של טוקנים JWT בהשוואה לטוקנים מבוססים (SWT) וטוקנים מבוססים SAML.

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

מבחינת אבטחה, SWT יכול להיות חתום באופן סימטרי רק על ידי סיקרט באמצעות אלגוריתם HMAC. עם זאת, טוקניםמסוגי JWT וכן SAML יכולים להשתמש בזוג מפתחות ציבוריים/פרטיים בצורה של אישור X.509 לחתימה. חתימה על XML עם חתימה דיגיטלית XML מבלי להציג פערי אבטחה מעורפלים בהשוואה לפשטות של חתימה עם JSON.

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

JWT עם Azure AD

שבודקים תעבורת Azure AD באמצעות Fiddler כל כל Web Debugger, ניתן להבחין שכותרת האימות עבור רוב הבקשות תכיל משהו שנקרא טוקן "Bearer" שהוא מחרוזת ארוכה, ועל פני השטח, בלתי קריא. טוקנים אלה הם "המפתחות לממלכה" בעולם של Azure AD מפתחות אלה מגיעים בפורמט JWT.

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

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

SAML מתייחס גם לטוקנים למתן שמות לפרוטוקולים, מה שיכול להיות מבלבל. JWT ו OAuth הם ספציפיים יותר; OAuth הוא הפרוטוקול, JWT הוא הטוקן.

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

אם כך, במידה ויש לי יישום באמצעות JWT איך תיראה הדרישה?

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

כאמור, כל התקשורת הזו מתרחשת באמצעות HTTPS.

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

השאר תגובה

error: Content is protected !!