רשימת משימות אבטחה

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

תכונות האבטחה הבאות עוזרות לכם ליצור אפליקציות מאובטחות:

  • ארגז החול של אפליקציות Android, שמבודד את נתוני האפליקציה ואת ביצוע הקוד מאפליקציות אחרות.
  • מסגרת לאפליקציות עם הטמעות חזקות של פונקציונליות אבטחה נפוצה, כמו קריפטוגרפיה, הרשאות ותקשורת מאובטחת בין תהליכים (IPC).
  • טכנולוגיות כמו address space layout randomization‏ (ASLR),‏ no-execute‏ (NX),‏ ProPolice,‏ safe_iop,‏ OpenBSD dlmalloc ו-calloc ו-Linux mmap_min_addr כדי לצמצם את הסיכונים שקשורים לשגיאות נפוצות בניהול זיכרון.
  • הרשאות שהמשתמשים העניקו כדי להגביל את הגישה לתכונות המערכת ולנתוני המשתמשים.
  • הרשאות שהוגדרו על ידי האפליקציה כדי לשלוט בנתוני האפליקציה לפי אפליקציה.

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

אימות

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

כדי לשפר את חוויית האימות של המשתמשים, אפשר לשלב את האפליקציה עם Credential Manager. Credential Manager היא ספריית Android Jetpack שמאחדת את תמיכת ה-API ברוב שיטות האימות העיקריות, כולל מפתחות גישה, סיסמאות ופתרונות כניסה מאוחדת כמו כניסה באמצעות חשבון Google.

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

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

שלמות האפליקציה

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

אחסון נתונים

אחת מהבעיות הנפוצות ביותר באבטחה של אפליקציות ב-Android היא האם לאפליקציות אחרות יש גישה לנתונים ששמורים במכשיר. יש שלוש דרכים בסיסיות לשמירת נתונים במכשיר:

  • אחסון פנימי
  • אחסון חיצוני
  • ספקי תוכן

בקטעים הבאים מתוארות בעיות האבטחה שמשויכות לכל גישה.

אחסון פנימי

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

מומלץ להימנע מהשימוש במצבים MODE_WORLD_WRITEABLE ו-MODE_WORLD_READABLE לקבצים של IPC, כי הם הוצאו משימוש. הם לא מאפשרים להגביל את הגישה לנתונים לאפליקציות מסוימות, ואין בהם אפשרות לשלוט בפורמט הנתונים. אם אתם רוצים לשתף את הנתונים שלכם עם תהליכים של אפליקציות אחרות, מומלץ להשתמש במקום זאת בספק תוכן, שמציע הרשאות קריאה וכתיבה לאפליקציות אחרות ויכול להעניק הרשאות דינמיות על בסיס כל מקרה לגופו.

אחסון חיצוני

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

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

ספקי תוכן

ספקי תוכן מציעים מנגנון אחסון מובנה שאפשר להגביל לאפליקציה שלכם או לייצא אותו כדי לאפשר גישה לאפליקציות אחרות. אם אתם לא מתכוונים לתת לאפליקציות אחרות גישה ל-ContentProvider, צריך לסמן אותו בתור android:exported=false במניפסט של האפליקציה. אחרת, צריך להגדיר את המאפיין android:exported לערך true כדי לאפשר לאפליקציות אחרות לגשת לנתונים השמורים.

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

אם אתם משתמשים בספק תוכן כדי לשתף נתונים רק בין האפליקציות שלכם, מומלץ להשתמש במאפיין android:protectionLevel עם הגנה ברמה signature. הרשאות חתימה לא מחייבות אישור מהמשתמש, ולכן הן מספקות חוויית משתמש טובה יותר וגישה מבוקרת יותר לנתונים של ספק התוכן כשהאפליקציות שגולשות בנתונים חתומות באותו מפתח.

ספקי תוכן יכולים גם לספק גישה מפורטת יותר על ידי הצהרה על המאפיין android:grantUriPermissions ושימוש בדגלים FLAG_GRANT_READ_URI_PERMISSION ו-FLAG_GRANT_WRITE_URI_PERMISSION באובייקט Intent שמפעיל את הרכיב. אפשר להגביל את היקף ההרשאות האלה עוד יותר באמצעות האלמנט <grant-uri-permission>.

כשאתם ניגשים לספק תוכן, כדאי להשתמש בשיטות שאילתות עם פרמטרים כמו query,‏ update ו-delete() כדי למנוע הזרקת SQL פוטנציאלית ממקורות לא מהימנים. חשוב לזכור ששימוש בשיטות עם פרמטרים לא מספיק אם הארגומנט selection נוצר על ידי שרשור של נתוני משתמשים לפני שליחתם לשיטה.

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

הרשאות

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

בקשות הרשאה

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

אם אפשר, כדאי לתכנן את האפליקציה כך שלא תצטרכו לבקש הרשאות. לדוגמה, במקום לבקש גישה לפרטי המכשיר כדי ליצור מזהה ייחודי, אפשר ליצור UUID לאפליקציה. (מידע נוסף זמין בקטע נתוני משתמשים). לחלופין, במקום להשתמש באחסון חיצוני (שדורש הרשאה), אפשר לאחסן נתונים באחסון פנימי.

בנוסף לבקשת הרשאות, האפליקציה יכולה להשתמש ברכיב <permission> כדי להגן על IPC שחשוף לאפליקציות אחרות, כמו ContentProvider, ויש בו מידע רגיש לאבטחה. באופן כללי, מומלץ להשתמש באמצעי בקרת גישה אחרים מלבד הרשאות שמאושרות על ידי משתמשים, במידת האפשר, כי הרשאות יכולות לבלבל משתמשים. לדוגמה, כדאי להשתמש ברמת הגנה על חתימות בהרשאות לתקשורת IPC בין אפליקציות שסופקו על ידי מפתח יחיד.

לא לדלוף נתונים שמוגנים באמצעות הרשאות. המצב הזה מתרחש כשהאפליקציה חושפת נתונים באמצעות IPC שזמינים רק כי לאפליקציה יש הרשאה לגשת לנתונים האלה. יכול להיות שללקוחות של ממשק ה-IPC של האפליקציה לא תהיה אותה הרשאת גישה לנתונים. פרטים נוספים על התדירות וההשפעות הפוטנציאליות של הבעיה הזו מופיעים במאמר המחקר Permission Re-Delegation: Attacks and Defenses, שפורסם ב-USENIX.

הגדרות של הרשאות

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

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

אם עדיין צריך ליצור הרשאה חדשה, מגדירים אותה במניפסט של האפליקציה באמצעות הרכיב <permission>. אפליקציות שמשתמשות בהרשאה החדשה יכולות להפנות אליה על ידי הוספת רכיב <uses-permission> לקובצי המניפסט שלהן. אפשר גם להוסיף הרשאות באופן דינמי באמצעות השיטה addPermission().

אם יוצרים הרשאה עם רמת ההגנה 'מסוכנת', יש כמה דברים מורכבים שצריך לקחת בחשבון:

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

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

רשתות

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

רשתות IP

הרשתות ב-Android לא שונות באופן משמעותי מסביבות אחרות של Linux. העיקר הוא לוודא שמשתמשים בפרוטוקולים המתאימים למידע רגיש, כמו HttpsURLConnection לתעבורת אינטרנט מאובטחת. מומלץ להשתמש ב-HTTPS במקום ב-HTTP בכל מקום שבו יש תמיכה ב-HTTPS בשרת, כי מכשירים ניידים מתחברים לעיתים קרובות לרשתות לא מאובטחות, כמו נקודות Wi-Fi ציבוריות.

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

חלק מהאפליקציות משתמשות ביציאות רשת של localhost לטיפול ב-IPC רגיש. אל תשתמשו בגישה הזו, כי לממשקי ה-API האלה יש גישה לאפליקציות אחרות במכשיר. במקום זאת, צריך להשתמש במנגנון IPC של Android שבו אפשר לבצע אימות, למשל באמצעות Service. קישור לכתובת ה-IP הלא ספציפית INADDR_ANY גרוע יותר משימוש ב-loopback, כי הוא מאפשר לאפליקציה לקבל בקשות מכל כתובת IP.

חשוב לוודא שאתם לא סומכים על נתונים שהורדתם מ-HTTP או מפרוטוקולים לא מאובטחים אחרים. זה כולל אימות של קלט ב-WebView וכל התשובות לכוונות שהונפקות כנגד HTTP.

רשתות טלפוניה

פרוטוקול Short Message Service‏ (SMS) תוכנן בעיקר לתקשורת בין משתמשים, והוא לא מתאים לאפליקציות שרוצות להעביר נתונים. בגלל המגבלות של SMS, מומלץ להשתמש ב-Firebase Cloud Messaging ‏ (FCM) וברשתות IP כדי לשלוח הודעות נתונים משרת אינטרנט לאפליקציה במכשיר של המשתמש.

חשוב לדעת שהודעות SMS לא מוצפנות ולא עוברות אימות חזק ברשת או במכשיר. באופן ספציפי, כל נמען של הודעת SMS צריך לצפות שיכול להיות שמשתמש זדוני שלח את הודעת ה-SMS לאפליקציה. אל תסתמכו על נתוני SMS לא מאומתים כדי לבצע פקודות רגישות. חשוב לדעת ש-SMS יכול להיות נתון לזיוף ו/או ליירטור ברשת. במכשיר Android עצמו, הודעות SMS מועברות ככוונות שידור, כך שאפשר לקרוא אותן או לתעד אותן באפליקציות אחרות שיש להן את ההרשאה READ_SMS.

אימות קלט

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

אם אתם משתמשים בקוד מקומי, כל נתון שנקרא מקבצים, מתקבל ברשת או מתקבל מ-IPC עלול לגרום לבעיית אבטחה. הבעיות הנפוצות ביותר הן מלאי יתר במאגר, שימוש אחרי שחרור ושגיאות של שגיאה אחת. מערכת Android כוללת כמה טכנולוגיות, כמו ASLR ומניעת ביצוע נתונים (DEP), שמפחיתות את האפשרות לנצל את השגיאות האלה, אבל הן לא פותרות את הבעיה הבסיסית. כדי למנוע את נקודות החולשה האלה, צריך לטפל בזהירות ב-pointers ולנהל את מאגרי הנתונים.

שפות דינמיות שמבוססות על מחרוזות, כמו JavaScript ו-SQL, גם הן חשופות לבעיות באימות הקלט בגלל תווים של בריחה והחדרת סקריפט.

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

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

נתוני משתמש

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

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

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

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

אם נדרש מזהה ייחודי גלובלי (GUID), יוצרים מספר גדול וייחודי ושומרים אותו. אל תשתמשו במזהי טלפון כמו מספר הטלפון או ה-IMEI, שעשויים להיות משויכים למידע אישי. הנושא הזה מוסבר בהרחבה בדף שיטות מומלצות למזהים ייחודיים.

חשוב להיזהר כשכותבים ביומני המכשיר. ב-Android, יומנים הם משאב משותף וזמינים לאפליקציה עם ההרשאה READ_LOGS. למרות שנתוני יומן הטלפון הם זמניים ונמחקים אחרי הפעלה מחדש, רישום לא הולם של פרטי משתמשים ביומן עלול לגרום לדליפת נתוני משתמשים לאפליקציות אחרות בטעות. בנוסף לאי-תיעוד של פרטים אישיים מזהים ביומן, כדאי להגביל את השימוש ביומן באפליקציות ייצור. כדי להטמיע את זה בקלות, אפשר להשתמש בדגלי ניפוי באגים ובכיתות Log בהתאמה אישית עם רמות רישום ביומן שקל להגדיר.

WebView

מכיוון ש-WebView צורך תוכן אינטרנט שיכול לכלול HTML ו-JavaScript, שימוש לא תקין יכול לגרום לבעיות נפוצות באבטחת האינטרנט, כמו פריצה מסוג XSS (הזרקת JavaScript). מערכת Android כוללת כמה מנגנונים לצמצום היקף הבעיות האפשריות האלה, על ידי הגבלת היכולות של WebView לפונקציונליות המינימלית שנדרשת לאפליקציה.

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

חשוב להשתמש ב-addJavaScriptInterface() בזהירות רבה, כי הוא מאפשר ל-JavaScript להפעיל פעולות ששמורות בדרך כלל לאפליקציות ל-Android. אם אתם משתמשים בו, חשוב לחשוף את addJavaScriptInterface() רק לדפי אינטרנט שמהם כל הקלט מהימן. אם מותר להזין קלט לא מהימן, יכול להיות ש-JavaScript לא מהימן יוכל להפעיל שיטות של Android באפליקציה. באופן כללי, מומלץ לחשוף את addJavaScriptInterface() רק ל-JavaScript שמכיל קובץ ה-APK של האפליקציה.

אם האפליקציה שלכם ניגשת למידע אישי רגיש באמצעות WebView, מומלץ להשתמש בשיטה clearCache() כדי למחוק את כל הקבצים שמאוחסנים באופן מקומי. אפשר גם להשתמש בכותרות בצד השרת, כמו no-store, כדי לציין שאפליקציה לא צריכה לשמור תוכן מסוים במטמון.

במכשירים שפועלות בהם פלטפורמות ישנות יותר מ-Android 4.4‏ (רמת API 19), נעשה שימוש בגרסה של webkit שיש בה כמה בעיות אבטחה. כפתרון עקיף, אם האפליקציה שלכם פועלת במכשירים האלה, היא צריכה לוודא שאובייקטים מסוג WebView מציגים רק תוכן מהימן. כדי לוודא שהאפליקציה לא חשופה לנקודות חולשה פוטנציאליות ב-SSL, צריך להשתמש באובייקט האבטחה הניתן לעדכון Provider כפי שמתואר במאמר עדכון ספק האבטחה להגנה מפני ניצול לרעה של SSL. אם האפליקציה שלכם צריכה ליצור עיבוד (רנדור) של תוכן מהאינטרנט הפתוח, כדאי לספק עיבוד משלכם כדי שתוכלו לעדכן אותו בתיקוני האבטחה האחרונים.

בקשות לקבלת פרטי כניסה

בקשות לקבלת פרטי כניסה הן וקטור להתקפה. ריכזנו כאן כמה טיפים שיעזרו לכם לשפר את האבטחה של בקשות פרטי הכניסה באפליקציות ל-Android.

צמצום החשיפה של פרטי הכניסה

  • הימנעות מבקשות מיותרות של פרטי כניסה כדי להפוך את התקפות הפישינג לבולטות יותר ולצמצם את הסיכוי שהן יצליחו, כדאי לצמצם את התדירות שבה מבקשים מהמשתמשים להזין את פרטי הכניסה שלהם. במקום זאת, צריך להשתמש בטוקן הרשאה ולרענן אותו. בקשו רק את המידע המינימלי הנדרש מהפרטים האישיים כדי לבצע אימות והרשאה.
  • אחסון מאובטח של פרטי הכניסה. אפשר להשתמש ב-Credential Manager כדי להפעיל אימות ללא סיסמה באמצעות מפתחות גישה, או כדי להטמיע כניסה מאוחדת באמצעות סכמות כמו 'כניסה באמצעות חשבון Google'. אם אתם חייבים להשתמש באימות סיסמה מסורתי, אל תשמרו מזהי משתמשים וסיסמאות במכשיר. במקום זאת, מבצעים אימות ראשוני באמצעות שם המשתמש והסיסמה שהמשתמש סיפק, ולאחר מכן משתמשים באסימון הרשאה לטווח קצר וספציפי לשירות.
  • הגבלת היקף ההרשאות אל תבקשו הרשאות רחבות למשימות שדורשות היקף מצומצם יותר.
  • הגבלת אסימוני הגישה שימוש בפעולות של אסימונים לטווח קצר ובקריאות ל-API.
  • הגבלת שיעורי האימות בקשות אימות או הרשאה מהירות ורצופות יכולות להיות סימן להתקפת כוח גס. כדאי להגביל את השיעורים האלה לתדירות סבירה, תוך שמירה על חוויית שימוש פונקציונלית ונוחה באפליקציה.

שימוש באימות מאובטח

  • הטמעת מפתחות גישה הפעלת מפתחות גישה כמעבר מאובטח ונוח יותר לסיסמאות.
  • מוסיפים מידע ביומטרי. כדאי להציע למשתמשים את האפשרות להשתמש באימות ביומטרי, כמו טביעת אצבע או זיהוי פנים, כדי לשפר את האבטחה.
  • שימוש בספקי זהויות מאוחדים. Credential Manager תומך בספקי אימות מאוחד, כמו כניסה באמצעות חשבון Google.
  • הצפנת התקשורת שימוש ב-HTTPS ובטכנולוגיות דומות כדי להבטיח שהנתונים שהאפליקציה שולחת ברשת מוגנים.

איך מנהלים את החשבון בצורה מאובטחת

  • אפשר להתחבר לשירותים שזמינים למספר אפליקציות באמצעות AccountManager. משתמשים בכיתה AccountManager כדי להפעיל שירות מבוסס-ענן, ולא מאחסנים סיסמאות במכשיר.
  • אחרי שמשתמשים ב-AccountManager כדי לאחזר Account, צריך להשתמש ב-CREATOR לפני שמעבירים פרטי כניסה, כדי שלא מעבירים בטעות פרטי כניסה לאפליקציה הלא נכונה.
  • אם פרטי הכניסה משמשים רק אפליקציות שאתם יוצרים, תוכלו לאמת את האפליקציה שמקבלת גישה ל-AccountManager באמצעות checkSignatures. לחלופין, אם רק אפליקציה אחת משתמשת בפרטי הכניסה, אפשר להשתמש ב-KeyStore לאחסון.

חשוב להישאר ערניים

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

ניהול מפתחות API

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

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

הקטע הזה מיועד לשתי קבוצות של מפתחי Android: אלה שעובדים עם צוותי התשתית בצינור עיבוד הנתונים שלהם ל-Continuous Delivery, ואלה שמפרסמים אפליקציות עצמאיות ב-Play Store. בקטע הזה מפורטות שיטות מומלצות לטיפול במפתחות API, כדי שהאפליקציה תוכל לתקשר עם שירותים בצורה מאובטחת.

יצירה ואחסון

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

אחסון מפתחות מאובטח

כדי לשפר את האבטחה של ניהול המפתחות, מומלץ להשתמש ב-Android Keystore ולהצפין את המפתחות השמורים באמצעות כלי חזק כמו Tink Java.

החרגה של בקרת מקורות

לעולם אל תיצרו התחייבות (commit) למפתחות API במאגר קוד המקור. הוספת מפתחות API לקוד המקור עלולה לחשוף את המפתחות למאגרים ציבוריים, לדוגמאות קוד משותפות ולקבצים ששותפו בטעות. במקום זאת, מומלץ להשתמש בפלאגינים של Gradle, כמו secrets-gradle-plugin, כדי לעבוד עם מפתחות API בפרויקט.

מפתחות ספציפיים לסביבה

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

בקרת גישה ושימוש

שיטות מאובטחות לשימוש במפתחות API הן חיוניות להגנה על ה-API ועל המשתמשים. כך מכינים את המפתחות לאבטחה אופטימלית:

  • יצירת מפתחות ייחודיים לכל אפליקציה: שימוש במפתחות API נפרדים לכל אפליקציה כדי לזהות גישה שנחשפה ולבודד אותה.
  • הטמעת הגבלות IP: אם אפשר, כדאי להגביל את השימוש במפתח API לכתובות IP או לטווח כתובות IP ספציפיים.
  • הגבלת השימוש במפתח של אפליקציה לנייד: אפשר להגביל את השימוש במפתח API לאפליקציות ספציפיות לנייד על ידי הוספת האפליקציות לחבילה עם המפתח או באמצעות אישורי אפליקציה.
  • רישום ביומן ומעקב אחרי פעילות חשודה: הטמעת מנגנונים למעקב ולרישום ביומן של השימוש ב-API כדי לזהות פעילות חשודה ולמנוע ניצול לרעה פוטנציאלי.

הערה: השירות צריך לספק תכונות להגבלת מפתחות לחבילה או לפלטפורמה מסוימת. לדוגמה, Google Maps API מגביל את הגישה למפתחות לפי שם החבילה ומפתח החתימה.

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

רוטציית מפתחות ותוקף מפתחות

כדי לצמצם את הסיכון לגישה לא מורשית דרך נקודות חולשה לא ידועות ב-API, חשוב לבצע רוטציה של מפתחות ה-API באופן קבוע. תקן ISO 27001 מגדיר מסגרת תאימות לתדירות ביצוע רוטציית מפתחות. ברוב המקרים, תקופת רוטציית מפתחות של 90 ימים עד 6 חודשים תספיק. הטמעה של מערכת יעילה לניהול מפתחות יכולה לעזור לכם לייעל את התהליכים האלה, ולשפר את היעילות של רוטציית המפתחות ואת הצורך בתוקף שלהם.

שיטות מומלצות כלליות

  • שימוש ב-SSL/HTTPS: תמיד צריך להשתמש בתקשורת HTTPS כדי להצפין את בקשות ה-API.
  • הצמדת אישורים: כדי להוסיף שכבת אבטחה, כדאי להשתמש בהצמדת אישורים כדי לבדוק אילו אישורים נחשבים תקפים.
  • אימות וחיטוי של קלט משתמש: אימות וחיטוי של קלט משתמש כדי למנוע התקפות הזרקה שעלולות לחשוף מפתחות API.
  • פעולה בהתאם לשיטות המומלצות בתחום האבטחה: הטמעת שיטות מומלצות כלליות לאבטחה בתהליך הפיתוח, כולל שיטות תכנות מאובטחות, בדיקות קוד וסריקת נקודות חולשה.
  • עדכונים: מומלץ להתעדכן באמצעי האבטחה העדכניים ביותר ובשיטות המומלצות לניהול מפתחות API.
  • ערכות SDK עדכניות: חשוב לוודא שערכות ה-SDK והספריות מעודכנות לגרסה האחרונה.

קריפטוגרפיה

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

חשוב לדעת אילו ספקי אבטחה של Java Cryptography Architecture‏ (JCA) משמשים את התוכנה. נסו להשתמש ברמה הגבוהה ביותר של הטמעת המסגרת הקיימת שיכולה לתמוך בתרחיש לדוגמה שלכם. אם רלוונטי, משתמשים בספקים ש-Google מספקת לפי הסדר ש-Google מציינת.

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

אם אתם צריכים להטמיע פרוטוקול משלכם, אל תטמיעו אלגוריתמים קריפטוגרפיים משלכם. שימוש באלגוריתמים קריפטוגרפיים קיימים, כמו ההטמעות של AES ו-RSA שסופקו בכיתה Cipher. בנוסף, כדאי לפעול לפי השיטות המומלצות הבאות:

  • שימוש ב-AES של 256 ביט למטרות מסחריות. (אם האפשרות הזו לא זמינה, משתמשים ב-AES 128-bit).
  • משתמשים בגדלים של מפתחות ציבוריים ב-224 או ב-256 ביט לקריפטוגרפיה של עקומה אליפטית (EC).
  • מתי משתמשים במצבי חסימה של CBC,‏ CTR או GCM
  • הימנעו משימוש חוזר ב-IV/במונה במצב CTR. מוודאים שהם קריפטוגרפיים אקראיים.
  • כשמשתמשים בהצפנה, מטמיעים את תקינות הנתונים באמצעות מצב CBC או CTR עם אחת מהפונקציות הבאות:
    • HMAC-SHA1
    • HMAC-SHA-256
    • HMAC-SHA-512
    • מצב GCM

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

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

תקשורת בין תהליכים (IPC)

חלק מהאפליקציות מנסים להטמיע IPC באמצעות שיטות מסורתיות של Linux, כמו שקעי רשת וקבצים משותפים. עם זאת, מומלץ להשתמש במקום זאת בפונקציות המערכת של Android ל-IPC, כמו Intent, ‏ Binder או Messenger עם Service ו-BroadcastReceiver. מנגנוני ה-IPC של Android מאפשרים לאמת את הזהות של האפליקציה שמתחברת ל-IPC ולהגדיר מדיניות אבטחה לכל מנגנון IPC.

רכיבי אבטחה רבים משותפים בין מנגנוני IPC. אם מנגנון ה-IPC לא מיועד לשימוש באפליקציות אחרות, צריך להגדיר את המאפיין android:exported לערך false ברכיב המניפסט של הרכיב, למשל ברכיב <service>. האפשרות הזו שימושית לאפליקציות שמכילות כמה תהליכים באותו UID, או אם בשלב מאוחר בפיתוח אתם מחליטים שלא רוצים לחשוף פונקציונליות כ-IPC, אבל אתם לא רוצים לכתוב מחדש את הקוד.

אם אפליקציות אחרות יכולות לגשת ל-IPC, תוכלו להחיל מדיניות אבטחה באמצעות האלמנט <permission>. אם ה-IPC הוא בין אפליקציות שבבעלותכם וחתומים באותו מפתח, השתמשו בהרשאה signature-level ב-android:protectionLevel.

כוונות

בפעילויות ובמקלטי שידורים, כוונות (intents) הן המנגנון המועדף ל-IPC אסינכררוני ב-Android. בהתאם לדרישות של האפליקציה, תוכלו להשתמש ב-sendBroadcast, ב-sendOrderedBroadcast או בכוונה מפורשת לרכיב ספציפי באפליקציה. מטעמי אבטחה, עדיף להשתמש בכוונות מפורשות.

זהירות: אם אתם משתמשים ב-intent כדי לקשר ל-**Service**, השתמשו ב-intent מפורש כדי לשמור על האבטחה של האפליקציה. שימוש בכוונה משתמעת כדי להפעיל שירות הוא סיכון אבטחה, כי אי אפשר לדעת איזה שירות יגיב לכוונה, והמשתמש לא יכול לראות איזה שירות מופעל. החל מגרסה Android 5.0‏ (רמת API 21), המערכת תיצור חריגה אם תפעילו את **bindService()** עם כוונה משתמעת.

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

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

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

שירותים

Service משמש לעתים קרובות כדי לספק פונקציונליות לאפליקציות אחרות. לכל סוג שירות צריכה להיות הצהרה תואמת של <service> בקובץ המניפסט שלו.

כברירת מחדל, השירותים לא מיוצאים ואי אפשר להפעיל אותם באף אפליקציה אחרת. עם זאת, אם מוסיפים מסנני כוונות להצהרת השירות, הוא מיוצא כברירת מחדל. מומלץ להצהיר באופן מפורש על המאפיין android:exported כדי לוודא שהוא יפעל כמצופה. אפשר להגן על שירותים גם באמצעות המאפיין android:permission. כך אפליקציות אחרות יצטרכו להצהיר על רכיב <uses-permission> תואם במניפסט שלהן כדי שיוכלו להפעיל, להפסיק או לקשר לשירות.

הערה: אם האפליקציה שלכם מטרגטת ל-Android 5.0 (רמת API‏ 21) ואילך, השתמשו ב-**JobScheduler** כדי להפעיל שירותי רקע.

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

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

ממשקי Binder ו-Messenger

השימוש ב-Binder או ב-Messenger הוא המנגנון המועדף ל-IPC בסגנון RPC ב-Android. הם מספקים ממשקים מוגדרים היטב שמאפשרים אימות הדדי של נקודות הקצה, במקרה הצורך.

מומלץ לתכנן את ממשקי האפליקציה כך שלא יהיה צורך לבצע בדיקות הרשאות ספציפיות לממשק. אובייקטים מסוג Binder ו-Messenger לא מפורטים במניפסט של האפליקציה, ולכן אי אפשר להחיל עליהם הרשאות מוצהרות ישירות. בדרך כלל, הן יורשות הרשאות שהוגדרו במניפסט של האפליקציה עבור Service או Activity שבהם הן מיושמות. אם אתם יוצרים ממשק שדורש אימות ו/או אמצעי בקרת גישה, עליכם להוסיף את אמצעי הבקרה האלה באופן מפורש כקוד בממשק Binder או Messenger.

אם אתם מספקים ממשק שדורש אמצעי בקרת גישה, תוכלו להשתמש ב-checkCallingPermission() כדי לוודא שלמבצע הקריאה החוזרת יש את ההרשאה הנדרשת. חשוב לעשות זאת במיוחד לפני שמקבלים גישה לשירות בשם מבצע הקריאה החוזרת, כי הזהות של האפליקציה מועברת לממשקים אחרים. אם מפעילים ממשק שמסופק על ידי Service, ההפעלה של bindService() עשויה להיכשל אם אין לכם הרשאה לגשת לשירות הנתון. אם אתם צריכים לאפשר לתהליך חיצוני לקיים אינטראקציה עם האפליקציה שלכם, אבל אין לו את ההרשאות הנדרשות כדי לעשות זאת, תוכלו להשתמש בשיטה clearCallingIdentity(). השיטה הזו מבצעת את הקריאה לממשק של האפליקציה כאילו האפליקציה עצמה מבצעת את הקריאה, ולא המתקשר החיצוני. תוכלו לשחזר את ההרשאות של מבצע הקריאה מאוחר יותר באמצעות השיטה restoreCallingIdentity().

מידע נוסף על ביצוע IPC באמצעות שירות זמין במאמר שירותים מקושרים.

מקלטי שידורים

BroadcastReceiver מטפל בבקשות אסינכרוניות שמתחילות ב-Intent.

כברירת מחדל, מכשירים מקבלים מיוצאים וכל אפליקציה אחרת יכולה להפעיל אותם. אם ה-BroadcastReceiver מיועד לשימוש באפליקציות אחרות, כדאי להחיל הרשאות אבטחה על מקלטים באמצעות האלמנט <receiver> במניפסט של האפליקציה. כך אפליקציות ללא ההרשאות המתאימות לא יוכלו לשלוח כוונה ל-BroadcastReceiver.

אבטחה באמצעות קוד שנטען באופן דינמי

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

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

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

אבטחה במכונה וירטואלית

Dalvik היא המכונה הווירטואלית (VM) של Android בסביבת זמן הריצה. Dalvik נוצר במיוחד עבור Android, אבל הרבה מהחששות לגבי קוד מאובטח במכונות וירטואליות אחרות רלוונטיים גם ל-Android. באופן כללי, אין צורך לדאוג לבעיות אבטחה שקשורות למכונה הווירטואלית. האפליקציה פועלת בסביבת ארגז חול מאובטח, כך שתהליכים אחרים במערכת לא יכולים לגשת לקוד או לנתונים הפרטיים שלכם.

אם אתם רוצים לקבל מידע נוסף על אבטחת מכונות וירטואליות, כדאי לעיין בספרות הקיימת בנושא. שני מקורות המידע הפופולריים ביותר הם:

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

  • מכונות וירטואליות מסוימות, כמו JVM או סביבת זמן ריצה של ‎ .NET, משמשות כגבול אבטחה ומבודדות את הקוד מיכולות מערכת ההפעלה הבסיסית. ב-Android, המכונה הווירטואלית של Dalvik היא לא גבול אבטחה – ארגז החול של האפליקציה מיושם ברמת מערכת ההפעלה, כך ש-Dalvik יכול לפעול עם קוד מקורי באותה אפליקציה ללא אילוצי אבטחה.
  • מכיוון שהנפח האחסון במכשירים ניידים מוגבל, מפתחים נוטים ליצור אפליקציות מודולריות ולהשתמש בחיבור דינמי של כיתות. כשעושים זאת, צריך להביא בחשבון גם את המקור שבו מאחזרים את הלוגיקה של האפליקציה וגם את המיקום שבו שומרים אותה באופן מקומי. אין להשתמש בחיבור דינמי של כיתות ממקורות לא מאומתים, כמו מקורות רשת לא מאובטחים או אחסון חיצוני, כי יכול להיות שהקוד הזה ישתנה כך שיכלול התנהגות זדונית.

אבטחה בקוד Native

באופן כללי, מומלץ להשתמש ב-Android SDK לפיתוח אפליקציות, במקום להשתמש בקוד מקורי באמצעות Android NDK. אפליקציות שנוצרות באמצעות קוד מקורי מורכבות יותר, פחות ניידות וסביר יותר שיכללו שגיאות נפוצות של פגיעה בזיכרון, כמו זליגת נתונים במאגר (buffer overflow).

Android נוצר באמצעות ליבה של Linux, והיכרות עם השיטות המומלצות לאבטחת הפיתוח ב-Linux שימושית במיוחד אם אתם משתמשים בקוד מקורי. שיטות האבטחה של Linux חורגות מהיקף המסמך הזה, אבל אחד מהמשאבים הפופולריים ביותר הוא Secure Programming HOWTO – Creating Secure Software.

הבדל חשוב בין Android לבין רוב סביבות Linux הוא ארגז החול של האפליקציות. ב-Android, כל האפליקציות פועלות בארגז החול של האפליקציה, כולל אלה שנכתבו בקוד מקורי. מפתחים שמכירים את Linux יכולים לחשוב על זה כך: לכל אפליקציה מוקצה מזהה משתמש (UID) ייחודי עם הרשאות מוגבלות מאוד. תוכלו לקרוא על כך בהרחבה במאמר סקירה כללית על אבטחת Android. מומלץ להכיר את ההרשאות של האפליקציה גם אם אתם משתמשים בקוד מקומי.