במסמך הזה מוסבר איך מפתחי אפליקציות יכולים להשתמש באמצעי האבטחה של Android כדי להגדיר הרשאות משלהם. כשאפליקציה מגדירה הרשאות בהתאמה אישית, היא יכולה לשתף את המשאבים והיכולות שלה עם אפליקציות אחרות. מידע נוסף על הרשאות זמין בסקירה הכללית על הרשאות.
רקע
Android היא מערכת הפעלה עם הפרדת הרשאות, שבה כל אפליקציה פועלת עם זהות מערכת נפרדת (מזהה משתמש ומזהה קבוצה של Linux). חלקים מהמערכת מופרדים גם לזהויות נפרדות. כך Linux מבודדת את האפליקציות זו מזו ומהמערכת.
אפליקציות יכולות לחשוף את הפונקציונליות שלהן לאפליקציות אחרות על ידי הגדרת הרשאות שאפליקציות אחרות יכולות לבקש. הם יכולים גם להגדיר הרשאות שיהיו זמינות באופן אוטומטי לכל אפליקציה אחרת שחתומה עם אותו אישור.
חתימה על אפליקציות
כל קובצי ה-APK חייבים להיות חתומים באמצעות אישור שהמפתח הפרטי שלו נמצא אצל המפתח. האישור לא צריך להיות חתום על ידי רשות אישורים. באפליקציות ל-Android מותר להשתמש באישורים בחתימה עצמית, וזה גם מקובל. המטרה של אישורים ב-Android היא להבחין בין יוצרי האפליקציות. כך המערכת יכולה להעניק לאפליקציות גישה להרשאות ברמת החתימה או לדחות את הגישה, וגם לאשר או לדחות בקשה של אפליקציה לקבל את אותה זהות Linux כמו של אפליקציה אחרת.
הענקת הרשאות חתימה אחרי זמן הייצור של המכשיר
החל מ-Android 12 (רמת API 31), המאפיין knownCerts להרשאות ברמת החתימה מאפשר לכם להפנות לתקצירים של אישורי חתימה ידועים בזמן ההצהרה.
אתם יכולים להצהיר על המאפיין knownCerts ולהשתמש בדגל knownSigner במאפיין protectionLevel של האפליקציה, כדי להגדיר הרשאה ספציפית ברמת החתימה. לאחר מכן, המערכת מעניקה את ההרשאה הזו לאפליקציה שמבקשת אותה, אם אחד מהחותמים בשושלת החתימה של האפליקציה המבקשת, כולל החותם הנוכחי, תואם לאחד מהתקצירים שהוצהרו עם ההרשאה במאפיין knownCerts.
הדגל knownSigner מאפשר למכשירים ולאפליקציות להעניק הרשאות חתימה לאפליקציות אחרות בלי צורך לחתום על האפליקציות בזמן הייצור והמשלוח של המכשיר.
מזהי משתמשים וגישה לקבצים
בזמן ההתקנה, מערכת Android נותנת לכל חבילה מזהה משתמש ייחודי של Linux. הזהות נשארת קבועה כל עוד החבילה נמצאת במכשיר. במכשיר אחר, לאותה חבילה יכול להיות מזהה UID שונה. מה שחשוב הוא שלכל חבילה יש מזהה UID ייחודי במכשיר נתון.
מכיוון שאכיפת האבטחה מתבצעת ברמת התהליך, הקוד של שתי חבילות לא יכול בדרך כלל לפעול באותו תהליך, כי הן צריכות לפעול כמשתמשי Linux שונים.
כל הנתונים שמאוחסנים על ידי אפליקציה מוקצים למזהה המשתמש של אותה אפליקציה, ובדרך כלל חבילות אחרות לא יכולות לגשת אליהם.
למידע נוסף על מודל האבטחה של Android, קראו את הסקירה הכללית על אבטחה ב-Android.
הגדרה ואכיפה של הרשאות
כדי לאכוף הרשאות משלכם, קודם צריך להצהיר עליהן בקובץ AndroidManifest.xml באמצעות רכיב אחד או יותר מסוג
<permission>.
מוסכמה למתן שמות
המערכת לא מאפשרת לכמה חבילות להצהיר על הרשאה עם אותו שם, אלא אם כל החבילות חתומות באותו אישור. אם חבילה מצהירה על הרשאה, המערכת גם לא מאפשרת למשתמש להתקין חבילות אחרות עם אותו שם הרשאה, אלא אם החבילות האלה חתומות באותו אישור כמו החבילה הראשונה.
מומלץ להוסיף להרשאות קידומת עם שם החבילה של האפליקציה, באמצעות מתן שמות בסגנון דומיין הפוך, ואחריו .permission. ואז תיאור של היכולת שההרשאה מייצגת, ב-SNAKE_CASE באותיות רישיות. לדוגמה, com.example.myapp.permission.ENGAGE_HYPERSPACE.
אם תפעלו לפי ההמלצה הזו, תוכלו להימנע מהתנגשויות בין שמות ולזהות בבירור את הבעלים ואת המטרה של הרשאה מותאמת אישית.
דוגמה
לדוגמה, אפליקציה שצריכה לשלוט באילו אפליקציות אחרות יכולות להתחיל את אחת מהפעילויות שלה יכולה להצהיר על הרשאה לפעולה הזו באופן הבא:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" > <permission android:name="com.example.myapp.permission.DEADLY_ACTIVITY" android:label="@string/permlab_deadlyActivity" android:description="@string/permdesc_deadlyActivity" android:permissionGroup="android.permission-group.COST_MONEY" android:protectionLevel="dangerous" /> ... </manifest>
המאפיין
protectionLevel נדרש והוא מציין למערכת איך להודיע למשתמשים על אפליקציות שדורשות את ההרשאה, או אילו אפליקציות יכולות להחזיק בהרשאה, כפי שמתואר במסמכי התיעוד המקושרים.
המאפיין android:permissionGroup הוא אופציונלי ומשמש רק כדי לעזור למערכת להציג הרשאות למשתמש. ברוב המקרים, מגדירים את זה לקבוצת מערכת רגילה (שמופיעה ב-android.Manifest.permission_group), אבל אפשר גם להגדיר קבוצה בעצמכם, כמו שמתואר בקטע הבא.
מומלץ להשתמש בקבוצה קיימת, כי זה מפשט את ממשק המשתמש של ההרשאות שמוצג למשתמש.
צריך לספק גם תווית וגם תיאור להרשאה. אלה משאבי מחרוזת שהמשתמש יכול לראות כשהוא צופה ברשימת הרשאות (android:label) או בפרטים של הרשאה אחת (android:description). התווית קצרה: כמה מילים שמתארות את הפונקציונליות העיקרית שההרשאה מגינה עליה. התיאור הוא כמה משפטים שמסבירים מה ההרשאה מאפשרת למחזיק לעשות. המוסכמה שלנו היא תיאור של שני משפטים, שבהם המשפט הראשון מתאר את ההרשאה והמשפט השני מזהיר את המשתמש מפני סוג הדברים שיכולים להשתבש אם האפליקציה מקבלת את ההרשאה.
דוגמה לתווית ולתיאור של ההרשאה CALL_PHONE:
<string name="permlab_callPhone">directly call phone numbers</string> <string name="permdesc_callPhone">Allows the app to call non-emergency phone numbers without your intervention. Malicious apps may cause unexpected calls on your phone bill.</string>
יצירת קבוצת הרשאות
כמו שמוצג בקטע הקודם, אתם יכולים להשתמש במאפיין android:permissionGroup כדי לעזור למערכת לתאר את ההרשאות למשתמש. ברוב המקרים, מגדירים את זה לקבוצת מערכת רגילה (שמופיעה ב-android.Manifest.permission_group), אבל אפשר גם להגדיר קבוצה משלכם באמצעות <permission-group>.
הרכיב <permission-group> מגדיר תווית לקבוצת הרשאות – גם אלה שהוצהרו במניפסט באמצעות רכיבי <permission> וגם אלה שהוצהרו במקומות אחרים. ההגדרה הזו משפיעה רק על האופן שבו ההרשאות מקובצות כשהן מוצגות למשתמש. הרכיב <permission-group> לא מציין את ההרשאות ששייכות לקבוצה, אלא נותן לקבוצה שם.
כדי להוסיף הרשאה לקבוצה, מקצים את שם הקבוצה למאפיין permissionGroup של הרכיב <permission>.
הרכיב <permission-tree> מצהיר על מרחב שמות לקבוצת הרשאות שמוגדרות בקוד.
המלצות להרשאות בהתאמה אישית
אתם יכולים להגדיר הרשאות בהתאמה אישית לאפליקציות שלכם ולבקש הרשאות בהתאמה אישית מאפליקציות אחרות על ידי הגדרת רכיבי <uses-permission>.
עם זאת, חשוב לבדוק היטב אם יש צורך בכך.
- אם אתם מפתחים חבילת אפליקציות שחושפות פונקציונליות אחת לשנייה, נסו לתכנן את האפליקציות כך שכל הרשאה תוגדר פעם אחת בלבד. צריך לעשות את זה אם האפליקציות לא חתומות כולן באותו אישור. גם אם כל האפליקציות חתומות באותו אישור, מומלץ להגדיר כל הרשאה פעם אחת בלבד.
- אם הפונקציונליות זמינה רק לאפליקציות שחתומות באותה חתימת אפליקציה כמו האפליקציה שמספקת את הפונקציונליות, יכול להיות שתוכלו להימנע מהגדרה של הרשאות בהתאמה אישית באמצעות בדיקות חתימה. כשאחת מהאפליקציות שלכם שולחת בקשה לאפליקציה אחרת שלכם, האפליקציה השנייה יכולה לוודא ששתי האפליקציות חתומות באותו אישור לפני שהיא נענית לבקשה.
אם נדרשת הרשאה מותאמת אישית, כדאי לבדוק אם רק אפליקציות שחתומות על ידי אותו מפתח כמו האפליקציה שמבצעת את בדיקת ההרשאה צריכות לגשת אליה – למשל, כשמטמיעים תקשורת מאובטחת בין תהליכים (IPC) בין שתי אפליקציות של אותו מפתח. אם כן, מומלץ להשתמש בהרשאות חתימה. הרשאות חתימה הן שקופות למשתמש, והן מונעות הרשאות שדורשות אישור מהמשתמש, שעלולות לבלבל את המשתמשים.
המשך קריאה על:
<uses-permission>- מאמרי העזרה של ה-API לתג המניפסט שמצהיר על הרשאות המערכת הנדרשות לאפליקציה.
אולי יעניין אותך גם:
- סקירה כללית בנושא אבטחה ב-Android
- דיון מפורט על מודל האבטחה של פלטפורמת Android.