איך יצרנו את הכרטיסייה WebAuthn ל-Chrome DevTools

פוואז מוחמד
פוואז מוחמד
נינה סטרגנו
נינה סטרגנו

ה-Web Authentication API, המוכר גם בשם WebAuthn, מאפשר לשרתים להשתמש בקריפטוגרפיה של מפתח ציבורי – במקום בסיסמאות – כדי לרשום ולאמת משתמשים. לשם כך היא מאפשרת אינטגרציה בין השרתים האלה לבין גורמי אימות חזקים. מאמתים אלה יכולים להיות מכשירים פיזיים ייעודיים (למשל מפתחות אבטחה) או משולבים בפלטפורמות (למשל קוראי טביעות אצבע). מידע נוסף על WebAuthn אפשר למצוא כאן בכתובת webauthn.guide.

נקודות חולשה למפתחים

לפני הפרויקט הזה, ל-WebAuthn לא הייתה תמיכה מובנית בניפוי באגים ב-Chrome. מפַתח שבנה אפליקציה שהשתמשה ב-WebAuth דרש גישה לאימותים פיזיים. הדבר היה קשה במיוחד משתי סיבות:

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

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

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

הפתרון: כרטיסיית WebAuthn חדשה

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

כרטיסיית WebAuthn חדשה

הטמעה

ההוספה של תמיכה בניפוי באגים ל-WebAuthn כללה שני שלבים.

תהליך בשני חלקים

חלק 1: הוספה של דומיין WebAuthn לפרוטוקול Chrome DevTools

בשלב הראשון, הטמענו דומיין חדש ב-Chrome DevTools Protocol (CDP) שמתחבר ל-handler שמתקשר עם הקצה העורפי של WebAuthn.

ה-CDP מחבר את הקצה הקדמי של כלי הפיתוח ל-Chromium. במקרה שלנו, השתמשנו בפעולות לדומיין WebAuthn כדי לגשר בין הכרטיסייה WebAuthn DevTools לבין ההטמעה של WebAuthn ב-Chromium.

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

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

(יש לקרוא את הקוד)

חלק 2: בניית הכרטיסייה שגלויה למשתמשים

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

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

המודל

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

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

(יש לקרוא את הקוד)

התצוגה

כרטיסיית WebAuthn חדשה

אנחנו משתמשים בתצוגה כדי לספק את ממשק המשתמש שמפתח יכול למצוא בכניסה לכלי הפיתוח. הוא מכיל:

  1. סרגל כלים להפעלת סביבה של מאמת חשבונות וירטואלי.
  2. קטע להוספת מאמתים.
  3. קטע למאמתים שנוצרו.

(יש לקרוא את הקוד)

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

סרגל הכלים

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

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

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

הוספת הקטע 'מאמת חשבונות'

הוספת הקטע 'מאמת חשבונות'

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

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

התצוגה 'מאמת חשבונות'

התצוגה 'מאמת חשבונות'

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

השם של מאמת החשבונות

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

טבלת פרטי הכניסה

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

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

הלחצן 'פעיל'

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

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

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

  1. המשתמש לוחץ על לחצן הבחירה פעיל עבור המאמת X, ושולח בקשה ל-CDP כדי להגדיר את X כפעיל. לחצן הבחירה פעיל של X מסומן והסימון של כל שאר הפריטים יבוטל.

  2. מיד לאחר מכן, המשתמש לוחץ על לחצן הבחירה פעיל עבור המאמת Y ושולח בקשה ל-CDP להגדיר את Y כפעיל. לחצן הבחירה פעיל של Y נבחר. כל שאר האפשרויות, כולל X, מבוטלות.

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

  4. בקצה העורפי, הקריאה להגדרת X כפעיל הושלמה וטופלה. X פעיל עכשיו וכל שאר המאמתים, כולל Y, לא.

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

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

כך זה נראה:


 async _setActiveAuthenticator(authenticatorId) {
   await this._clearActiveAuthenticator();
   await this._model.setAutomaticPresenceSimulation(authenticatorId, true);
   this._activeId = authenticatorId;
   this._updateActiveButtons();
 }
 
 _updateActiveButtons() {
   const authenticators = this._authenticatorsView.getElementsByClassName('authenticator-section');
   Array.from(authenticators).forEach(authenticator => {
     authenticator.querySelector('input.dt-radio-button').checked =
         authenticator.getAttribute('data-authenticator-id') === this._activeId;
   });
 }
 
 async _clearActiveAuthenticator() {
   if (this._activeId) {
     await this._model.setAutomaticPresenceSimulation(this._activeId, false);
   }
   this._activeId = null;
 }

מדדי שימוש

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

  1. ספירה בכל פעם שהכרטיסייה WebAuthn נפתחה בכלי הפיתוח. האפשרות הזו עלולה להוביל לספירת יתר, כי מישהו עלול לפתוח את הכרטיסייה בלי להשתמש בה בפועל.

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

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

סיכום

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

לפניך כמה מקורות מידע לקבלת מידע נוסף על WebAuthn:

מורידים את הערוצים של התצוגה המקדימה.

כדאי להשתמש ב-Chrome Canary, Dev או בטא כדפדפן הפיתוח שמוגדר כברירת מחדל. ערוצי התצוגה המקדימה האלה מעניקים לך גישה לתכונות החדשות של כלי הפיתוח, בודקים ממשקי API מתקדמים של פלטפורמת האינטרנט ומוצאים בעיות באתר לפני שהמשתמשים נתקלים בבעיות!

יצירת קשר עם צוות כלי הפיתוח ל-Chrome

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

  • שלחו לנו הצעה או משוב בכתובת crbug.com.
  • כדי לדווח על בעיה בכלי הפיתוח, לוחצים על אפשרויות נוספות   עוד   > עזרה > דיווח על בעיות בכלי הפיתוח בכלי הפיתוח.
  • אפשר לשלוח ציוץ אל @ChromeDevTools.
  • אפשר לכתוב תגובות לגבי 'מה חדש' בסרטוני YouTube או בקטע 'טיפים לשימוש בכלי הפיתוח' בסרטוני YouTube.