במסמך הזה מוסבר איך מפתחי אפליקציות יכולים להשתמש בתכונות האבטחה של Android כדי להגדיר הרשאות משלהם. הגדרת הרשאות בהתאמה אישית מאפשרת לאפליקציה לשתף את המשאבים והיכולות שלה עם אפליקציות אחרות. מידע נוסף על הרשאות זמין במאמר סקירה כללית על הרשאות.
רקע
Android היא מערכת הפעלה עם הפרדת הרשאות, שבה כל אפליקציה פועלת עם זהות מערכת נפרדת (מזהה משתמש וקבוצה של Linux). חלקים מהמערכת מופרדים גם לזהויות נפרדות. כך, Linux מבודד אפליקציות זו מזו וממערכת ההפעלה.
אפליקציות יכולות לחשוף את הפונקציונליות שלהן לאפליקציות אחרות על ידי הגדרת הרשאות שאפשר לבקש מהן. הם יכולים גם להגדיר הרשאות שתהיינה זמינות באופן אוטומטי לכל אפליקציה אחרת שתחתום על אותו אישור.
חתימה על אפליקציות
כל חבילות ה-APK חייבות להיות חתומות באישור שהמפתח הפרטי שלו נמצא בידי המפתח. לא צריך לחתום על האישור על ידי רשות אישורים. מותר לאפליקציות ל-Android להשתמש באישורים בחתימה עצמית, וזה גם נפוץ. מטרת האישורים ב-Android היא להבדיל בין מפתחי האפליקציות. כך המערכת יכולה להעניק או לדחות לאפליקציות גישה להרשאות ברמת החתימה, ולהעניק או לדחות בקשה של אפליקציה לקבל את אותה זהות Linux כמו של אפליקציה אחרת.
מתן הרשאות חתימה אחרי זמן הייצור של המכשיר
החל מ-Android 12 (רמת API 31), המאפיין knownCerts
להרשאות ברמת החתימה מאפשר להפנות ל-digests של אישורי חתימה ידועים בזמן ההצהרה.
אפשר להצהיר על המאפיין 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.