קטגוריה ב-OWASP: MASVS-CODE: איכות הקוד
סקירה כללית
הסכנות שמשויכות להרשאות בהתאמה אישית נובעות מהעובדה שהגדרת ההרשאות בהתאמה אישית חסרה או שגויה, או מהשימוש לרעה במאפיין android:protectionLevel
התואם בתוך המניפסט.
לדוגמה, אפשר לנצל את הסיכונים האלה על ידי יצירת הרשאה מותאמת אישית עם אותו שם, אבל מוגדרת על ידי אפליקציה זדונית ומופעלות בה רמות הגנה שונות.
הרשאות בהתאמה אישית נועדו לאפשר שיתוף משאבים ויכולות עם אפליקציות אחרות. דוגמאות לשימוש לגיטימי בהרשאות מותאמות אישית יכולות להיות:
- שליטה בתקשורת בין תהליכים (IPC) בין שתי אפליקציות או יותר
- גישה לשירותים של צד שלישי
- הגבלת הגישה לנתונים המשותפים של אפליקציה
השפעה
ניצול נקודת החולשה הזו עלול לאפשר לאפליקציה זדונית לקבל גישה למשאבים שהיו אמורים להיות מוגנים. ההשלכות של נקודת החולשה תלויות במשאב המוגן ובהרשאות המשויכות לשירות האפליקציה המקורי.
סיכון: שגיאות הקלדה בהרשאות בהתאמה אישית
יכול להיות שתוצהר הרשאה מותאמת אישית במניפסט, אבל המערכת משתמשת בהרשאה מותאמת אישית אחרת כדי להגן על רכיבי Android שיוצאו, בגלל שגיאת הקלדה. אפליקציה זדונית יכולה לנצל אפליקציות שהכתיבו שגיאה בהרשאה, בשתי דרכים:
- רישום ההרשאה הזו קודם
- חיזוי האיות באפליקציות הבאות
כך יכולה להיגרם לאפליקציה גישה לא מורשית למשאבים או שליטה באפליקציית הקורבן.
לדוגמה, באפליקציה עם נקודת חולשה רוצים להגן על רכיב באמצעות ההרשאה READ_CONTACTS
, אבל בטעות כותבים את ההרשאה בצורה שגויה כ-READ_CONACTS
. אפליקציה זדונית יכולה לתבוע בעלות על READ_CONACTS
כי הוא לא בבעלות של אף אפליקציה (או המערכת), וכך לקבל גישה לרכיב המוגן. וריאנט נפוץ נוסף של נקודת החולשה הזו הוא android:permission=True
. ערכים כמו true
ו-false
, ללא קשר לשימוש באותיות רישיות, הם קלט לא חוקי להצהרת ההרשאה, והם מטופלים באופן דומה לשגיאות הקלדה אחרות בהצהרות הרשאה בהתאמה אישית. כדי לפתור את הבעיה, צריך לשנות את הערך של המאפיין android:permission
למחרוזת הרשאה תקינה. לדוגמה, אם לאפליקציה צריכה להיות גישה לאנשי הקשר של המשתמש, הערך של המאפיין android:permission
צריך להיות android.permission.READ_CONTACTS
.
פעולות מיטיגציה
בדיקות Lint ל-Android
כשמגדירים הרשאות בהתאמה אישית, כדאי להשתמש בבדיקות איתור שגיאות בקוד של Android כדי למצוא שגיאות הקלדה ושגיאות פוטנציאליות אחרות בקוד.
מוסכמה למתן שמות
כדאי להשתמש במוסכמה עקבית למתן שמות כדי להפוך שגיאות הקלדה לבולטות יותר. חשוב לבדוק היטב את הצהרות ההרשאות בהתאמה אישית במניפסט של האפליקציה כדי לאתר שגיאות הקלדה.
סיכון: הרשאות יתומים
הרשאות משמשות להגנה על משאבי האפליקציות. יש שני מיקומים שונים שבהם אפליקציה יכולה להצהיר על ההרשאות הנדרשות לגישה למשאבים:
- AndroidManifest.xml: מוגדרות מראש בקובץ AndroidManifest.xml (אם לא צוינו, נעשה שימוש בהרשאות
<application>
), למשל הרשאת ספק, הרשאת מקלט, הרשאת פעילות, הרשאת שירות. - קוד: רשום בקוד של סביבת זמן הריצה, למשל:
registerReceiver()
.
עם זאת, לפעמים ההרשאות האלה לא מוגדרות באמצעות תג <permission>
תואם במניפסט של קובץ APK במכשיר. במקרה כזה, הן נקראות הרשאות יתומים. המצב הזה יכול לקרות מכמה סיבות, למשל:
- יכול להיות חוסר סנכרון בין העדכונים במניפסט לבין הקוד עם בדיקת ההרשאות
- יכול להיות שה-APK עם ההרשאות לא נכלל ב-build, או שגרסה שגויה נכללה בו
- יכול להיות ששם ההרשאה בבדיקה או במניפסט כתוב בצורה שגויה
אפליקציה זדונית יכולה להגדיר הרשאה יתומה ולקבל אותה. אם זה יקרה, האפליקציות בעלות ההרשאות שמסתמכות על ההרשאה היתומה כדי להגן על רכיב מסוים עלולות להיפרץ.
במקרים שבהם האפליקציה בעלת ההרשאות משתמשת בהרשאה כדי להגן על רכיב כלשהו או להגביל אותו, היא עלולה להעניק לאפליקציה הזדונית גישה לרכיב הזה. לדוגמה, הפעלת פעילויות שמוגנות על ידי הרשאה, גישה לספק תוכן או שידור למקלט שידור שמוגן על ידי ההרשאה היתומה.
היא עלולה גם ליצור מצב שבו האפליקציה בעלת ההרשאות תישלה לחשוב שהאפליקציה הזדונית היא אפליקציה לגיטימית, וכתוצאה מכך היא תטען קבצים או תוכן.
פעולות מיטיגציה
חשוב לוודא שכל ההרשאות בהתאמה אישית שבהן האפליקציה משתמשת כדי להגן על רכיבים מוגדרות גם במניפסט.
האפליקציה משתמשת בהרשאות בהתאמה אישית my.app.provider.READ
ו-my.app.provider.WRITE
כדי להגן על הגישה לספק תוכן:
XML
<provider android:name="my.app.database.CommonContentProvider" android:readPermission="my.app.provider.READ" android:writePermission="my.app.provider.WRITE" android:exported="true" android:process=":myappservice" android:authorities="my.app.database.contentprovider"/>
האפליקציה גם מגדירה את ההרשאות המותאמות אישית האלה ומשתמשת בהן, וכך מונעת מאפליקציות זדוניות אחרות לעשות זאת:
XML
<permission android:name="my.app.provider.READ"/>
<permission android:name="my.app.provider.WRITE"/>
<uses-permission android:name="my.app.provider.READ" />
<uses-permission android:name="my.app.provider.WRITE" />
סיכון: שימוש לרעה ב-android:protectionLevel
המאפיין הזה מתאר את רמת הסיכון הפוטנציאלית בהרשאה, ומציין את התהליכים שהמערכת צריכה לפעול לפיהם כשהיא מחליטה אם להעניק את ההרשאה או לא.
פעולות מיטיגציה
הימנעות מרמת הגנה רגילה או מסוכנת
שימוש ב-protectionLevel
רגיל או מסכן בהרשאות שלכם אומר שרוב האפליקציות יכולות לבקש את ההרשאה ולקבל אותה:
- ב-'normal' צריך רק להצהיר עליו
- 'מסוכנים' יאושר על ידי משתמשים רבים
לכן, protectionLevels
האלה מספקים אבטחה מועטה.
שימוש בהרשאות חתימה (Android מגרסה 10 ואילך)
השתמשו ברמות הגנה על חתימות כשהדבר אפשרי. השימוש ביכולת הזו מבטיח שרק אפליקציות אחרות שחתומות על ידי אותו אישור כמו האפליקציה שיצרה את ההרשאה יכולות לגשת לתכונות המוגנות האלה. חשוב לוודא שאתם משתמשים באישור חתימה ייעודי (לא לשימוש חוזר) ושאתם שומרים אותו בצורה מאובטחת ב-keystore.
מגדירים הרשאה בהתאמה אישית באופן הבא במניפסט:
XML
<permission
android:name="my.custom.permission.MY_PERMISSION"
android:protectionLevel="signature"/>
להגביל את הגישה, למשל לפעילות, רק לאפליקציות שקיבלו את ההרשאה המותאמת אישית הזו, באופן הבא:
XML
<activity android:name=".MyActivity" android:permission="my.custom.permission.MY_PERMISSION"/>
כל אפליקציה אחרת שחתמתם עליה באותו אישור שבו חתומה האפליקציה שהצהירה על ההרשאה בהתאמה אישית הזו תקבל גישה לפעילות .MyActivity
, ותצטרך להצהיר עליה באופן הבא במניפסט שלה:
XML
<uses-permission android:name="my.custom.permission.MY_PERMISSION" />
היזהרו מהרשאות מותאמות אישית לחתימה (ב-Android גרסה 10 ואילך)
אם האפליקציה שלכם מטרגטת את Android בגרסה 10 ואילך, בכל פעם שההרשאות בהתאמה אישית של האפליקציה יוסרו בגלל הסרות או עדכונים, יכול להיות שאפליקציות זדוניות עדיין יוכלו להשתמש בהרשאות בהתאמה אישית האלה ולעקוף את הבדיקות. הסיבה לכך היא נקודת חולשה של הסלמת הרשאות (CVE-2019-2200
) שתוקנה ב-Android 10.
זו אחת הסיבות (לצד הסיכון לתנאי מרוץ) לכך שאנחנו ממליצים להשתמש בבדיקות חתימות במקום בהרשאות בהתאמה אישית.
סיכון: מרוץ תהליכים
אם אפליקציה לגיטימית A
מגדירה הרשאה מותאמת אישית לחתימה שבה משתמשות אפליקציות X
אחרות, אבל היא תוסר לאחר מכן, אפליקציה זדונית B
יכולה להגדיר את אותה הרשאה מותאמת אישית עם protectionLevel
שונה, למשל normal. כך, ל-B
תהיה גישה לכל הרכיבים באפליקציות X
שמוגנים על ידי ההרשאה בהתאמה אישית הזו, בלי צורך לחתום עליה באמצעות אותו אישור כמו האפליקציה A
.
אותו דבר יקרה אם B
יותקן לפני A
.
פעולות מיטיגציה
אם רוצים שהרכיב יהיה זמין רק לאפליקציות שחתמו עליו באותו חתימת האפליקציה שסיפקה אותו, יכול להיות שאפשר להימנע מהגדרת הרשאות בהתאמה אישית כדי להגביל את הגישה לרכיב הזה. במקרה כזה, אפשר להשתמש בבדיקות חתימות. כשאחת מהאפליקציות ששלחתם בקשה בשבילה שולחת בקשה לאפליקציה אחרת, האפליקציה השנייה יכולה לאמת ששתי האפליקציות חתומות על ידי אותו אישור לפני שהיא ממלאת את הבקשה.
משאבים
- צמצום מספר הבקשות להרשאות
- סקירה כללית על הרשאות
- תיאור רמות ההגנה
- CustomPermissionTypo Android Lint
- איך משתמשים ב-Android Lint
- סקירה מחקרית עם הסבר מעמיק על ההרשאות ב-Android וממצאים מעניינים מבדיקות fuzz