טופס אימות

שיקולי אבטחה במהלך האימות

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

בקרת סיסמאות נכונה

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

  • תערובת של אותיות גדולות וקטנות כאחד.
  • תערובת של אותיות ומספרים.
  • לפחות תו מיוחד אחד: !@#$%^&*() וכו'.

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

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

NIST
הודעת שגיאה המבקשת מהמשתמש לבחור סיסמה חזקה יותר

יישום זה בעצמך עשוי להיות משימה מרתיעה, אך למרבה המזל, ישנם שירותים וספריות שנועדו לעזור לך. ה zxcvbn ספרייה זמינה בשפות רבות היא אפשרות אחת. ה מנוקדת מסד הנתונים של סיסמאות מכיל מאות מיליוני סיסמאות פדוקות, שלפיהן ניתן לבדוק את הסיסמה הנבחר של המשתמש. אתה יכול לארח אותו באופן מקומי או להשתמש ב- API לתקשר איתו (באמצעות hashes כמובן!).

אם אתה מצפה שהמשתמשים שלך ידברו שפות שמשתמשות באלפבית לא לטיני, או בלטינית מורחבת (עם דיאקריטיות או אותיות מיוחדות כמו ø, æ, œ), תיאורטית מתן אפשרות ללוח המלא של תווי Unicode תגביר את האבטחה. זה ימנע את רוב התקפות הכוח הגס, שממילא מניח את תקני ASCII, וגם יגדיל מאוד את מספר השילובים האפשריים². למרות שזה אולי נשמע כמו עניין לא מובן מאליו, בפועל, עליך לקחת בחשבון שאתה עלול להיכשל בטיפול נכון ב-UTF-8 (למשל טיפול בתווים מקבילים מבחינה קנונית). טיפול לא נכון ב-Unicode עלול להפחית את השימושיות ואף להשפיע לרעה על האבטחה. עשה זאת רק אם אתה בטוח ביכולות שלך.
כהערה אחרונה, חשוב להגדיר הגבלת אורך מקסימלי. אם לא תעשה זאת עלולה לחשוף אותך לא סיסמה ארוכה DOS לִתְקוֹף. 64 תווים הוא גבול עליון טוב.

סיסמא

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

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

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

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

  1. גיבוב סיסמת מועמד.
  2. בודקים אם ה-hash תואם לסיסמה במסד הנתונים.

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

הכי טוב מתיחת מפתחות אלגוריתמים הזמינים היום עבור סיסמאות הם Argon2id ³, שזכה ב-2015 תחרות Hashing Hashing, ו PBKDF2 , שמומלץ על ידי NIST. אלה משתמשים בפונקציות גיבוב פשוטות נפוצות כמו SHA256 בתור 'קנדים אחוריים', אך מיישמים אותן אלפי פעמים ומוסיפים מלח אוטומטית. לָכֵן, לא השתמש ישירות בפונקציות גיבוב פשוטות כמו SHA או MD5 שאינן מיועדות לסיסמאות, וגם לא נסה לבנות שיטות משלך למתיחת מפתחות, זו משימה טיפשית.

TLS ואימות

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

TLS (Transport Layer Security) הוא הפרוטוקול היורש ל-SSL (Secure Socket Layer). בקיצור, TLS כולל תחילה הליך לחיצת יד המחייב את השרת לשלוח אישור מרשות מהימנה המעידה על הלגיטימיות שלו. לאחר מכן מחליפים מפתחות הצפנה באמצעות ה שיטת דפי-הלמן (מפתחות ציבוריים ופרטיים נוצרים). שאר הסשן מוצפן ומפוענח באמצעות מפתחות אלה.

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

אימות רב גורמים

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

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

  • שינוי סיסמאות.
  • ביצוע עסקאות כספיות.
  • השבתת MFA.
  • השגת גישת מנהל.

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

מניעת בוטים

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

פתר את reCAPTCHA
reCAPTCHA

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

הודעות שגיאה

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

  • הסיסמה הייתה שגויה.
  • החשבון לא קיים.
  • החשבון נעול, מושבת או חסום.

הודעת שגיאה נכונה ומאובטחת תהיה משהו כמו

"Login failed; Invalid user ID or password."

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

"If that email address is in our database, we will send you an email to reset your password."

ו

"A link to activate your account has been emailed to the address provided."

בהתאמה.

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

if (user_exists(username)) {
    String password_hash = hash(password);
    bool valid = lookup_credentials(username, password_hash);
    if (!valid) {
        return Error("Invalid Username or Password!");
    }
} else {
   return Error("Invalid Username or Password!");
}

יחזור מהר יותר אם המשתמש לא קיים, מה שהתוקף יכול לנצל, ואילו קוד זה

String password_hash = hash(password);
bool valid = lookup_credentials(username, password_hash);
if (!valid) {
   return Error("Invalid Username or Password!");
}

ייקח בערך אותו פרק זמן בשני המקרים.

אימות כניסה יחידה

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

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

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

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


¹ המכון הלאומי לתקנים וטכנולוגיה


² יש 143,859 תווי Unicode זמינים. זה אומר שיש מקסימום 143,8598 ≈ 1.83 × 1041 שילובי 8 תווים אפשריים. השווה ל-1288 = 7.2 × 1016 שילובים של ASCII.

יש להשתמש ב-ragon2id עם התצורות הבאות: 

  • m=37 MiB, t=1, p=1
  • m=15 MiB, t=2, p=1

כאשר m הוא הזיכרון המינימלי, t הוא מספר האיטרציות, ו-p הוא מידת ההקבלה. הם מקבילים באבטחה, אבל הראשון רעב יותר לזיכרון אבל פחות תובעני מהמעבד, ולהיפך. זכור להשתמש ב-Aragon2id גִרְסָה אַחֶרֶת.

⁴בעת גיבוב עם PBKDF2 יש להגדיר את מספר האיטרציות על סמך אלגוריתם הגיבוב הפנימי שבו נעשה שימוש. ההצעות הבאות שוות ערך באבטחה:

  • PBKDF2-HMAC-SHA1: 720,000 איטרציות
  • PBKDF2-HMAC-SHA256: 310,000 איטרציות
  • PBKDF2-HMAC-SHA512: 120,000 איטרציות
עבור לתוכן