הגדרה של הרשאה בהתאמה אישית לאפליקציה

במסמך הזה מוסבר איך מפתחי אפליקציות יכולים להשתמש בתכונות האבטחה של 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>. עם זאת, חשוב לבדוק היטב אם יש צורך בכך.

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

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

מידע נוסף על:

<uses-permission>
חומר עזר בנושא API לגבי תג המניפסט שמצהיר על הרשאות המערכת הנדרשות של האפליקציה.

נושאים נוספים שעשויים לעניין אותך:

סקירה כללית על אבטחת Android
דיון מפורט על מודל האבטחה של פלטפורמת Android.