BaClick

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

מאיר א. · מורה, מפתח ומייסד BaClick · · 4 דק׳ קריאה

עודכן:

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

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

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

הכלל הראשון: שום דבר לא נכתב ישירות מהמכשיר

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

שכבה שנייה: כללי הרשאה שבודקים כל שאילתה

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

שכבה שלישית: לדעת מאיפה הבקשה מגיעה

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

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

למפתחים: הדפוס המינימלי

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

match /households/{h}/balances/{kid} {
  allow read:  if isMember(h);
  allow write: if false;   // only the server writes
}

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

מקרי קצה ותקלות נפוצות

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

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

דריסת יתרה במקום רישום תנועה. שמירת "יתרה = 120" במקום "הפקדה של 20" מוחקת את ההיסטוריה - ואיתה את היכולת לגלות מה השתבש. אצלנו נשמר יומן מלא של כל התנועות.

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

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

ואם הילד שלכם באמת ניסה?

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

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

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

מה זה אומר בפועל למשפחה

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

שאלות נפוצות

מה קורה אם מישהו בכל זאת מוצא דרך לעקוף שכבה אחת?

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

האם הסתרת הקוד באפליקציה לא מספיקה?

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

זה אומר שאין שום דרך לילד "לשחק" עם המערכת בכלל?

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


כל שקל בהון בקליק עובר רק דרך השרת - בלי יוצא מן הכלל.

להמשך קריאה