דפוסי פריצה · 2 מתוך 5
ניחוש רציף בלי הגבלת קצב: כשמזהה בודד מאפשר סריקה של כל מסד הנתונים
זה הפוסט השני בסדרה על דפוסי הפריצה הנפוצים ביותר. אחרי הרשאה שבורה ברמת האובייקט (שבה שינוי מספר אחד בכתובת מספיק), מגיע הדפוס שמופיע כמעט תמיד לידו: כשאין מה שעוצר סקריפט מלנסות אלפי מספרים ברצף.
מה זה בעצם "ניחוש רציף בלי הגבלת קצב"?
לרוב הרשומות באפליקציה יש מזהה: מספר משתמש, מספר כרטיס, מספר זהות, לפעמים אפילו מספר טלפון. כשהמזהים רציפים או ניתנים לניחוש (1001, 1002, 1003, או תעודות זהות ישראליות בתחום מוכר), מספיק לתוקף לדעת איך נראית בקשה אחת תקינה. משם הוא כותב לולאה קצרה שמנסה את המספר הבא, ואת זה שאחריו, ואת זה שאחריו.
אם השרת מחזיר מידע על כל מזהה שקיים, ושום דבר לא מגביל כמה בקשות אפשר לשלוח בדקה, הפגם הקטן הופך לסריקה מלאה של מסד הנתונים. באנגלית קוראים לזה enumeration (או ID enumeration): "למנות" את כל המזהים הקיימים ולשאוב את מה שמצורף אליהם. הגבלת קצב (rate limiting) היא בדיוק המחסום שמונע מהלולאה הזו לרוץ חופשי.
שימו לב להבדל מדפוס 1: שם מספיק מזהה אחד זר כדי לקרוא רשומה אחת של מישהו אחר. כאן הסיפור הוא קנה מידה: אותה חולשה, אלפי פעמים בשנייה, עד שכל הרשימה אצל התוקף.
איך זה קורה בפועל
נניח שיש לכם מסך "אימות כרטיס" או "שחזור סיסמה לפי מספר זהות". הלקוח שולח מספר, והשרת מחזיר שם ומספר טלפון, "כדי לאשר שזה באמת אתם". עכשיו דמיינו סקריפט שעושה בדיוק את אותו דבר, רק עם רשימת מספרים רציפה:
החלק המטעה: לפעמים יש גם בדיקת התחברות, ולפעמים אפילו בדיקת בעלות חלקית, אבל אם אפשר לגלות אילו מזהים קיימים ומה מצורף אליהם בקצב גבוה, עדיין אפשר לבנות רשימה מלאה. והרבה פעמים אין אפילו צורך בהתחברות: מספיק endpoint ציבורי של "שחזור" או "אימות" שמחזיר יותר מדי מידע.
דוגמה מהעיתונות
אותו דפוס הופיע גם מחוץ לישראל: בנובמבר 2025 דיווחה TechCrunch על מערכות ניהול מושבעים במדינות בארה״ב עם מזהים רציפים ובלי הגבלה על ניסיונות התחברות, מה שאפשר למישהו לסרוק רשומות אישיות רגישות. ובדצמבר 2025 על אפליקציית הודעות "מאובטחת" בלי הגבלה על ניחוש מספרי טלפון.
קראו את הכתבה ב-TheMarker ←
איך פותרים את זה
אין כפתור קסם אחד: יש שכבות שצריכות לעבוד יחד:
- הגבלת קצב בצד השרת על כל endpoint שמחזיר מידע לפי מזהה שניתן לניחוש (שחזור סיסמה, אימות כרטיס, חיפוש משתמש, התחברות). אחרי X ניסיונות: האטה, נעילה זמנית, או CAPTCHA. בלי זה, כל שאר ההגנות נשחקות תחת סקריפט.
- מזהים שלא ניתנים לניחוש (UUID אקראי במקום 1001, 1002) מקטינים את הסיכון, אבל לא מחליפים הגבלת קצב, במיוחד כשהמזהה הוא מספר זהות או טלפון מהעולם האמיתי.
- פחות מידע בתשובה: "אם החשבון קיים שלחנו SMS" עדיף על "הנה השם והטלפון של בעל המספר". כל שדה שחוזר ב־200 הוא עוד שדה שאפשר לסרוק.
- ועדיין: בדיקת בעלות (דפוס 1), כדי שמזהה שנחשף לא יפתח רשומה של מישהו אחר.
שימו לב: להסתיר את המזהה בצד הלקוח, או "לא לפרסם את ה-API", זה לא פתרון. סקריפט לא צריך מסך יפה. הוא צריך כתובת שעובדת. ההגנה חייבת להיות על השרת, על כל ניסיון, גם אם הוא מגיע מכתובת IP משתנה או מחשבונות רבים.
איך בודקים אם האפליקציה שלכם חשופה לדפוס הזה
הבדיקה הזו קצרה, ושווה לעשות אותה על כל מסך שמקבל מזהה או מספר טלפון:
- מצאו נקודה שמקבלת מזהה (שחזור סיסמה, חיפוש כרטיס, פרופיל לפי מספר).
- שלחו ידנית כמה בקשות עם מזהים סמוכים (או טלפונים ברצף) וראו אם חוזר מידע שימושי.
- אם כן, נסו בקצב גבוה יותר (אפילו עם כלי פשוט או סקריפט קצר). אם השרת ממשיך לענות ב־200 בלי האטה ובלי 429, מצאתם את הדפוס.
- בדקו גם מה חוזר כשהמזהה לא קיים: תשובה שונה ("לא נמצא" מול "נשלח SMS") יכולה בעצמה לדלוף מי קיים במערכת.
אם תוך דקה־שתיים כבר יש בידיכם עשרות רשומות, אל תמתינו לכתבה הבאה בקפטן אינטרנט. תתקנו קודם את הקצב, ואז את כמות המידע שחוזרת בכל תשובה.
איך secureFlows פותר את זה מלכתחילה
ב-secureFlows הגישה למידע מבוססת על טוקן הפעלה של המשתמש, לא על מזהה רציף שהאפליקציה שלכם שולחת בכתובת. אין "לולאה על מספרי משתמש" שפותחת רשומות של אחרים, כי הרשומה משויכת לבעל הטוקן מההתחלה.
בנוסף, נתיבי התחברות רגישים מוגנים בהגבלת קצב בצד השרת, כדי שסקריפט ניחוש לא יוכל לרוץ חופשי מול נקודות הכניסה. כשבונים על התשתית הזו, אתם לא צריכים לזכור להוסיף את המחסום הזה בכל מסך שחזור בנפרד: הוא חלק מהשכבה שכל בקשה עוברת דרכה.
רוצים בידוד משתמשים והגבלת קצב מובנים בתשתית, בלי לסמוך על זיכרון של מפתח? לחצו על הכפתור למטה והתחילו לבנות עם secureFlows.
התחילו לבנות בחינם