«

»

Mar 15

הרשאות ב Android

הרשאות ב Android

אייקון permissions
 
 

רקע תאורטי:

 

גוגל מגינים על המשתמשים במכשיר האנדרואיד ע”י שיטת ה Permissions.

ז.א. שכל שירות/אפליקציה של גוגל מוגנת בהרשאה. אם אפליקציה רוצה לגשת ולהשתמש בשירות היא צריכה להצהיר על השימוש הזה בקובץ ה AndroidManifest.xml שלה ע”י הכרזה על uses-permission. בלי ההכרזה הזאת האפליקציה תקרוס בזמן ריצה כאשר ננסה להשתמש בשירות.

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

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

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

 

אבל, גם המנגנון הזה לא בהכרח מוגן ויש הרבה Exploits/Hacks – ניצולים, שמאפשרים שימוש בשירות שאמור להיות מוגן בלי להכריז על שימוש בהרשאה.

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

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

D/Finsky (27010): [1] InstallerImpl.requestInstall: Request install of <the_application_name_I_Installed>

v=8 for single_install

 

רשימה של כל ה Permissions שקיימים לשירותים של גוגל אפשר למצוא באתר:

http://developer.android.com/reference/android/Manifest.permission.html

 

כל ההצהרות לשימוש בשירות מוגדרות ב Manifest. לדוגמא ההצהרה לשימוש באינטרנט תעשה ע”י הוספה השורה הבאה ל Manifest:

<uses-permission android:name="android.permission.INTERNET" />

 

בנוסף לזאת, אפליקציה יכולה להגן על החלקים שלה (על ה Activities/Services/Broadcast Receivers ו Content Providers) בעזרת הרשאות. בין אם הרשאות קיימום של גוגל ובין אם הרשאה ספציפית שהיא מגדירה בשבילה ע”י שימוש בטאג של permission.

<permission android:description="string resource"
            android:icon="drawable resource"
            android:label="string resource"
            android:name="string"
            android:permissionGroup="string"
            android:protectionLevel=["normal" | "dangerous" | 
                                     "signature" | "signatureOrSystem"] />

 

description/icon/label אלה פרמטרים שנועדו בשביל להגדיר מה יוצג (אם יוצג) למשתמש, בעת בקשה של אפליקציה אחרת לשימוש במשאב (Activity וכו’…) של האפליקציה שלנו.

permissionGroup – להגדיר את ההרשאה לקבוצה והערך זה שם הקבוצה. אם מגדירים את השדה הזה, אפליקציה אחרת שתרצה לגשת למשאב שלנו תצטרך להצהיר ב Manifest שלה על .

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

 

protectionLevel:

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

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

Signature: הרשאה שנותנת גישה רק אם האפליקציה שביקשה את הגישה חתומה באותו key של האפליקציה המבקשת. למשתמש לא יוצג דיאלוג או התראה על זה. (וכמובן מכריזה על uses-permissions הזה)

SignatureOrSystem: כמו Signature רק שנותן הרשאות גם לכל אפליקציה שהיא system. (שמותקנות ב /system/app/).

 

מתי נאכף ה Permission שהגדרנו:

כאשר משתמש ינסה לבצע פעולה שאליו אין לו permission יזרק לו חריג מסוג: SecurityException

עבור Activity:

מגביל את מי שקורא ל Context.startActivity() או Context.StartActivityForResult().

עבור Service:

מגביל את מי שרוצה לעשות start או bind ל Service.

עבור Broadcast Receiver:

מגביל את מי שרוצה לשלוח broadcast ל receiver. הודעה של receiver מאפליקציה שלא מחריזה על ההרשאה לא תזרוק חריג, אבל ההודעה גם לא תגיע ל receiver.

עבור Content Provider:

במקרה הזה יש שני סוגים של permissions:

readPermission

מגביל את מי שרוצה לקרוא מה Content Provider ע”י:
ContentResolver.query()

writePermission

מגביל את מי שרוצה לכתוב ל Content Provider ע”י:
ContentResolver.update(), ContentResolver.delete(), ContentResolver.insert()

 
 
 

דוגמה והסבר:

 

בצד האפליקציה שאנחנו רוצים להגן עליה:

 

בקובץ ה Manifest:

1. ניצור permission משלנו שמגן על חלקים באפליקציה שלנו:

<permission
        android:name="co.il.lior.permissionsprotectedapplication.normal"
        android:description="@string/normal_description"
        android:label="co.il.lior.permissionsprotectedapplication.normal - Label"
        android:protectionLevel="normal" />

אנחנו מגדירים פה הרשאה מסוג normal שמזוהה ע”י השם שלה.

כל אפליקציה תוכל לגשת אם רק יהיה לה את ה uses permissions עם השם הזה שהגדרנו.

 

2. נגן על Activity מסוים בעזרת ה permission הזה שהגדרנו:

<activity
            android:name=".NormalProtectedActivity"
            android:label="@string/app_name"
            android:permission="co.il.lior.permissionsprotectedapplication.normal" >
            <intent-filter>
                <action android:name="co.il.lior.permissionsprotectedapplication.MyAction" />
            </intent-filter>
        </activity>

נשים לב שאנחנו חייבים להוסיף ל Activity איזה intent filter עם action, אחרת לא נוכל לשלוח intents מאפליקציה אחרת ל Activity.

 
 

בצד האפליקציה שמבצעת את הקריאות לאפליקציה שלנו:

 

בקובץ ה Manifest:

3. נגדיר שהאפליקציה משתמשת בהרשאות שהצהרנו עליהן באפליקציה המוגנת:

<uses-permission android:name="co.il.lior.permissionsprotectedapplication.normal" />

 

בקוד:

4. נקרא ל Activity באפליקציה המוגנת:

try {

	Intent intent = new Intent();
	intent.setComponent(new ComponentName("co.il.lior.permissionsprotectedapplication", "co.il.lior.permissionsprotectedapplication.NormalProtectedActivity"));
	startActivity(intent);

} catch(SecurityException e) {

	Toast.makeText(CallingActivity.this, "SecurityException", Toast.LENGTH_SHORT).show();
	e.printStackTrace();

}

כעת מכייון שהצהרנו על השימוש ב permission נוכל לבצע את הקריאה.

 

הערות:

נשים לב שאם נוריד את הצהרת ה uses permission באפליקציה הקוראת, נקבל SecurityException.

בנוסף אם היינו מגדירים את ההרשאה מסוג signature אז היינו מקבלים SecurityPermission אם החתימה שבה יצרנו את ה apk של האפליקציה הקוראת היה שונה מזה של האפליקציה המוגנת.

מניסויים שלי, במצב של חתימה שונה אם ההרשאה מוגדרת מסוג dangerous ולא signature גם נקבל SecurityException.

 
 

לינק להורדת הפרויקט לדוגמה

 

שימו לב שיש 2 פרוייקטים לדוגמה, אחד שמגן על עצמו בעזרת permissions והשני שקורא

בהצלחה !

Leave a Reply

Your email address will not be published.

אתם יכולים להשתמש באפשרויות ותגי ה-HTMLהבאים: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>