כך תוכלו לשמור על אמון המשתמשים ועל שלמות המכשיר.
בדף הזה מוצגות כמה שיטות מומלצות שיש להן השפעה חיובית משמעותית על האבטחה של האפליקציה.
אכיפת תקשורת מאובטחת
כשמגנים על הנתונים שמועברים בין האפליקציה שלכם לבין אפליקציות אחרות, או בין האפליקציה שלכם לבין אתר, משפרים את היציבות של האפליקציה ומגנים על הנתונים שאתם שולחים ומקבלים.
הגנה על התקשורת בין אפליקציות
כדי לתקשר בין אפליקציות בצורה בטוחה יותר, משתמשים ב-intents משתמעים עם כלי לבחירת אפליקציות, בהרשאות מבוססות חתימה ובספקי תוכן שלא מיוצאים.
הצגת כלי לבחירת אפליקציות
אם אפשר להפעיל לפחות שתי אפליקציות אפשריות במכשיר של המשתמש באמצעות אובייקט Intent מרומז, צריך להציג באופן מפורש את כלי בחירת האפליקציות. אסטרטגיית האינטראקציה הזו מאפשרת למשתמשים להעביר מידע רגיש לאפליקציה שהם סומכים עליה.
Kotlin
val intent = Intent(Intent.ACTION_SEND)
val possibleActivitiesList: List<ResolveInfo> =
packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)
// Verify that an activity in at least two apps on the user's device
// can handle the intent. Otherwise, start the intent only if an app
// on the user's device can handle the intent.
if (possibleActivitiesList.size > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
<b>val chooser = resources.getString(R.string.chooser_title).let { title ->
Intent.createChooser(intent, title)
}
startActivity(chooser)</b>
} else if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
Java
Intent intent = new Intent(Intent.ACTION_SEND);
List<ResolveInfo> possibleActivitiesList = getPackageManager()
.queryIntentActivities(intent, PackageManager.MATCH_ALL);
// Verify that an activity in at least two apps on the user's device
// can handle the intent. Otherwise, start the intent only if an app
// on the user's device can handle the intent.
if (possibleActivitiesList.size() > 1) {
// Create intent to show chooser.
// Title is something similar to "Share this photo with."
<b>String title = getResources().getString(R.string.chooser_title);
Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);</b>
} else if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
מידע קשור:
החלת הרשאות מבוססות-חתימה
כשמשתפים נתונים בין שתי אפליקציות שאתם שולטים בהן או שהן בבעלותכם, כדאי להשתמש בהרשאות מבוססות חתימה. ההרשאות האלה לא דורשות אישור מהמשתמש, אלא בודקות שהאפליקציות שמקבלות גישה לנתונים חתומות באמצעות אותו מפתח חתימה. לכן, ההרשאות האלה מציעות חוויית משתמש יעילה ומאובטחת יותר.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <permission android:name="my_custom_permission_name" android:protectionLevel="signature" />
מידע קשור:
איסור גישה לספקי התוכן של האפליקציה
אלא אם אתם מתכוונים לשלוח נתונים מהאפליקציה שלכם לאפליקציה אחרת שאתם לא הבעלים שלה, עליכם להגדיר במפורש שאפליקציות של מפתחים אחרים לא יוכלו לגשת לאובייקטים ContentProvider של האפליקציה שלכם. ההגדרה הזו חשובה במיוחד אם האפליקציה שלכם ניתנת להתקנה במכשירים עם Android בגרסה 4.1.1 (רמת API 16) או בגרסאות קודמות, כי מאפיין android:exported של רכיב <provider> מוגדר כ-true כברירת מחדל בגרסאות האלה של Android.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <application ... > <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.myapp.fileprovider" ... android:exported="false"> <!-- Place child elements of <provider> here. --> </provider> ... </application> </manifest>
בקשת פרטי כניסה לפני הצגת מידע רגיש
כשמבקשים מהמשתמשים פרטי כניסה כדי שיוכלו לגשת למידע רגיש או לתוכן פרימיום באפליקציה, צריך לבקש קוד אימות, סיסמה או קו ביטול נעילה, או פרטים ביומטריים כמו זיהוי פנים או טביעת אצבע.
במדריך בנושא אימות ביומטרי מוסבר איך לבקש פרטים ביומטריים.
החלת אמצעי אבטחה ברשת
בקטעים הבאים מוסבר איך לשפר את אבטחת הרשת של האפליקציה.
שימוש בתנועת TLS
אם האפליקציה שלכם מתקשרת עם שרת אינטרנט שיש לו אישור שהונפק על ידי רשות אישורים (CA) מוכרת ומהימנה, צריך להשתמש בבקשת HTTPS כמו הבקשה הבאה:
Kotlin
val url = URL("https://www.google.com")
val urlConnection = url.openConnection() as HttpsURLConnection
urlConnection.connect()
urlConnection.inputStream.use {
...
}
Java
URL url = new URL("https://www.google.com");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.connect();
InputStream in = urlConnection.getInputStream();
הוספת הגדרת אבטחת רשת
אם האפליקציה שלכם משתמשת ב-CA חדשים או מותאמים אישית, אתם יכולים להצהיר על הגדרות האבטחה של הרשת בקובץ תצורה. התהליך הזה מאפשר ליצור את ההגדרה בלי לשנות את הקוד של האפליקציה.
כדי להוסיף קובץ הגדרות אבטחה לרשת לאפליקציה, פועלים לפי השלבים הבאים:
- מצהירים על ההגדרה במניפסט של האפליקציה:
-
מוסיפים קובץ משאבים מסוג XML, שנמצא בכתובת
res/xml/network_security_config.xml.כדי לציין שכל התנועה לדומיינים מסוימים צריכה להשתמש ב-HTTPS, צריך להשבית את האפשרות clear-text:
<network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> ... </domain-config> </network-security-config>
במהלך תהליך הפיתוח, אפשר להשתמש ברכיב
<debug-overrides>כדי לאפשר במפורש אישורים שהמשתמשים התקינו. האלמנט הזה מבטל את ההגדרות הקריטיות לאבטחה של האפליקציה במהלך ניפוי הבאגים והבדיקות, בלי להשפיע על הגדרות הפרסום של האפליקציה. בקטע הקוד הבא מוצג איך מגדירים את האלמנט הזה בקובץ ה-XML של הגדרות אבטחת הרשת של האפליקציה:<network-security-config> <debug-overrides> <trust-anchors> <certificates src="user" /> </trust-anchors> </debug-overrides> </network-security-config>
<manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > <!-- Place child elements of <application> element here. --> </application> </manifest>
מידע קשור: הגדרת אבטחת הרשת
יצירת מנהל הרשאות שיתוף משלכם
כלי הבדיקה של TLS לא אמור לקבל כל אישור. יכול להיות שתצטרכו להגדיר מנהל אמון ולטפל בכל האזהרות לגבי TLS שמופיעות אם אחד מהתנאים הבאים רלוונטי לתרחיש השימוש שלכם:
- אתם מתקשרים עם שרת אינטרנט שיש לו אישור שחתום על ידי רשות אישורים (CA) חדשה או מותאמת אישית.
- המכשיר שבו אתם משתמשים לא בוטח ב-CA הזה.
- אי אפשר להשתמש בתצורה של אבטחת הרשת.
מידע נוסף על השלמת השלבים האלה מופיע בקטע על טיפול ברשות אישורים לא מוכרת.
מידע קשור:
שימוש זהיר באובייקטים של WebView
WebView
אובייקטים באפליקציה לא צריכים לאפשר למשתמשים לנווט לאתרים שלא נמצאים בשליטתכם. בכל הזדמנות שמתאפשרת, כדאי להשתמש ברשימת היתרים כדי להגביל את התוכן שנטען על ידי אובייקטים מסוג WebView באפליקציה.
בנוסף, אל תפעילו אף פעם תמיכה בממשק JavaScript, אלא אם אתם שולטים לחלוטין בתוכן באובייקטים WebView של האפליקציה ובוטחים בו.
שימוש בערוצי הודעות בפורמט HTML
אם האפליקציה שלכם חייבת להשתמש בתמיכה בממשק JavaScript במכשירים עם Android מגרסה 6.0 (רמת API 23) ואילך, צריך להשתמש בערוצי הודעות HTML במקום בתקשורת בין אתר לאפליקציה, כמו שמוצג בקטע הקוד הבא:
Kotlin
val myWebView: WebView = findViewById(R.id.webview)
// channel[0] and channel[1] represent the two ports.
// They are already entangled with each other and have been started.
val channel: Array<out WebMessagePort> = myWebView.createWebMessageChannel()
// Create handler for channel[0] to receive messages.
channel[0].setWebMessageCallback(object : WebMessagePort.WebMessageCallback() {
override fun onMessage(port: WebMessagePort, message: WebMessage) {
Log.d(TAG, "On port $port, received this message: $message")
}
})
// Send a message from channel[1] to channel[0].
channel[1].postMessage(WebMessage("My secure message"))
Java
WebView myWebView = (WebView) findViewById(R.id.webview);
// channel[0] and channel[1] represent the two ports.
// They are already entangled with each other and have been started.
WebMessagePort[] channel = myWebView.createWebMessageChannel();
// Create handler for channel[0] to receive messages.
channel[0].setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
@Override
public void onMessage(WebMessagePort port, WebMessage message) {
Log.d(TAG, "On port " + port + ", received this message: " + message);
}
});
// Send a message from channel[1] to channel[0].
channel[1].postMessage(new WebMessage("My secure message"));
מידע קשור:
מתן ההרשאות הנכונות
חשוב לבקש רק את מספר ההרשאות המינימלי שנדרש כדי שהאפליקציה תפעל בצורה תקינה. כשהאפליקציה כבר לא צריכה הרשאות, כדאי לבטל אותן.
שימוש בכוונות כדי לדחות הרשאות
בכל מקרה שאפשר, אל תוסיפו הרשאה לאפליקציה כדי להשלים פעולה שאפשר להשלים באפליקציה אחרת. במקום זאת, השתמשו ב-Intent כדי להעביר את הבקשה לאפליקציה אחרת שכבר יש לה את ההרשאה הנדרשת.
בדוגמה הבאה מוצג שימוש בכוונה כדי להפנות משתמשים לאפליקציית אנשי קשר במקום לבקש את ההרשאות READ_CONTACTS ו-WRITE_CONTACTS:
Kotlin
// Delegates the responsibility of creating the contact to a contacts app,
// which has already been granted the appropriate WRITE_CONTACTS permission.
Intent(Intent.ACTION_INSERT).apply {
type = ContactsContract.Contacts.CONTENT_TYPE
}.also { intent ->
// Make sure that the user has a contacts app installed on their device.
intent.resolveActivity(packageManager)?.run {
startActivity(intent)
}
}
Java
// Delegates the responsibility of creating the contact to a contacts app,
// which has already been granted the appropriate WRITE_CONTACTS permission.
Intent insertContactIntent = new Intent(Intent.ACTION_INSERT);
insertContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);
// Make sure that the user has a contacts app installed on their device.
if (insertContactIntent.resolveActivity(getPackageManager()) != null) {
startActivity(insertContactIntent);
}
בנוסף, אם האפליקציה צריכה לבצע קלט/פלט מבוסס-קבצים – כמו גישה לאחסון או בחירת קובץ – היא לא צריכה הרשאות מיוחדות כי המערכת יכולה להשלים את הפעולות בשם האפליקציה. עוד יותר טוב, אחרי שמשתמש בוחר תוכן בכתובת URI מסוימת, האפליקציה שקוראת מקבלת הרשאה למשאב שנבחר.
מידע קשור:
שיתוף נתונים בצורה מאובטחת בין אפליקציות
כדי לשתף את התוכן של האפליקציה עם אפליקציות אחרות בצורה מאובטחת יותר, מומלץ לפעול לפי השיטות המומלצות הבאות:
- אפשר לאכוף הרשאות קריאה בלבד או כתיבה בלבד לפי הצורך.
-
אפשר להעניק ללקוחות גישה חד-פעמית לנתונים באמצעות הדגלים
FLAG_GRANT_READ_URI_PERMISSIONו-FLAG_GRANT_WRITE_URI_PERMISSION. - כשמשתפים נתונים, צריך להשתמש בכתובות URI מסוג
content://ולא בכתובות URI מסוגfile://. דוגמאות לשימוש ב-FileProviderכדי לעשות את זה בשבילכם.
בקטע הקוד הבא אפשר לראות איך משתמשים בדגלים של הענקת הרשאות URI ובהרשאות של ספק תוכן כדי להציג קובץ PDF של אפליקציה באפליקציה נפרדת לצפייה בקובצי PDF:
Kotlin
// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("<b>content:</b>//com.example/personal-info.pdf")
// This flag gives the started app read access to the file.
<b>addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)</b>
}.also { intent ->
// Make sure that the user has a PDF viewer app installed on their device.
intent.resolveActivity(packageManager)?.run {
startActivity(intent)
}
}
Java
// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent viewPdfIntent = new Intent(Intent.ACTION_VIEW);
viewPdfIntent.setData(Uri.parse("<b>content://</b>com.example/personal-info.pdf"));
// This flag gives the started app read access to the file.
<b>viewPdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);</b>
// Make sure that the user has a PDF viewer app installed on their device.
if (viewPdfIntent.resolveActivity(getPackageManager()) != null) {
startActivity(viewPdfIntent);
}
הערה: הפעלת קבצים מהספרייה הראשית של האפליקציה שניתנת לכתיבה היא הפרה של W^X. לכן, אפליקציות לא מהימנות שמיועדות ל-Android 10 (רמת API 29) ומעלה לא יכולות להפעיל את exec() בקבצים שבספרייה הראשית של האפליקציה, אלא רק בקוד הבינארי שמוטמע בקובץ ה-APK של האפליקציה. בנוסף, אפליקציות שמיועדות ל-Android 10 ומעלה לא יכולות לשנות בזיכרון קוד הפעלה מקבצים שנפתחו באמצעות dlopen(). זה כולל קבצים של אובייקטים משותפים (.so) עם מיקומי טקסט.
מידע שקשור לנושא:
android:grantUriPermissions
אחסון נתונים בצורה בטוחה
יכול להיות שהאפליקציה שלכם דורשת גישה למידע רגיש של משתמשים, אבל הם יאפשרו לה גישה לנתונים שלהם רק אם הם בטוחים שתשמרו עליהם בצורה נאותה.
אחסון נתונים פרטיים באחסון הפנימי
לאחסן את כל הנתונים הפרטיים של המשתמשים באחסון הפנימי של המכשיר, שמוגדר כארגז חול לכל אפליקציה. האפליקציה לא צריכה לבקש הרשאה כדי להציג את הקבצים האלה, ואפליקציות אחרות לא יכולות לגשת אליהם. כאמצעי אבטחה נוסף, כשהמשתמש מסיר את ההתקנה של אפליקציה, המכשיר מוחק את כל הקבצים שהאפליקציה שמרה באחסון הפנימי.
בקטע הקוד הבא מוצגת דרך אחת לכתיבת נתונים לאחסון פנימי:
Kotlin
// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
val FILE_NAME = "sensitive_info.txt"
val fileContents = "This is some top-secret information!"
File(filesDir, FILE_NAME).bufferedWriter().use { writer ->
writer.write(fileContents)
}
Java
// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
final String FILE_NAME = "sensitive_info.txt";
String fileContents = "This is some top-secret information!";
try (BufferedWriter writer =
new BufferedWriter(new FileWriter(new File(getFilesDir(), FILE_NAME)))) {
writer.write(fileContents);
} catch (IOException e) {
// Handle exception.
}
בקטע הקוד הבא מוצגת הפעולה ההפוכה, קריאת נתונים מאחסון פנימי:
Kotlin
val FILE_NAME = "sensitive_info.txt"
val contents = File(filesDir, FILE_NAME).bufferedReader().useLines { lines ->
lines.fold("") { working, line ->
"$working\n$line"
}
}
Java
final String FILE_NAME = "sensitive_info.txt";
StringBuffer stringBuffer = new StringBuffer();
try (BufferedReader reader =
new BufferedReader(new FileReader(new File(getFilesDir(), FILE_NAME)))) {
String line = reader.readLine();
while (line != null) {
stringBuffer.append(line).append('\n');
line = reader.readLine();
}
} catch (IOException e) {
// Handle exception.
}
מידע קשור:
אחסון נתונים באחסון חיצוני בהתאם לתרחיש השימוש
כדאי להשתמש באחסון חיצוני לקבצים גדולים ולא רגישים שספציפיים לאפליקציה, וגם לקבצים שהאפליקציה משתפת עם אפליקציות אחרות. ממשקי ה-API הספציפיים שבהם תשתמשו תלויים בשאלה אם האפליקציה מיועדת לגשת לקבצים ספציפיים לאפליקציה או לגשת לקבצים משותפים.
אם קובץ לא מכיל מידע אישי או רגיש, אבל הוא שימושי למשתמש רק באפליקציה שלכם, כדאי לאחסן את הקובץ בספרייה ספציפית לאפליקציה באחסון חיצוני.
אם האפליקציה שלכם צריכה לגשת לקובץ או לאחסן קובץ שמספק ערך לאפליקציות אחרות, אתם צריכים להשתמש באחד מממשקי ה-API הבאים, בהתאם לתרחיש השימוש:
- קובצי מדיה: כדי לאחסן תמונות, קובצי אודיו וסרטונים שמשותפים בין אפליקציות ולגשת אליהם, צריך להשתמש ב-Media Store API.
- קבצים אחרים: כדי לאחסן סוגים אחרים של קבצים משותפים ולגשת אליהם, כולל קבצים שהורדו, משתמשים ב-Storage Access Framework.
בדיקת הזמינות של נפח האחסון
אם האפליקציה שלכם מתקשרת עם מכשיר אחסון חיצוני שאפשר להסיר, חשוב לזכור שהמשתמש יכול להסיר את מכשיר האחסון בזמן שהאפליקציה מנסה לגשת אליו. כוללים לוגיקה כדי לוודא שהתקן האחסון זמין.
בדיקת התוקף של הנתונים
אם האפליקציה משתמשת בנתונים מאחסון חיצוני, צריך לוודא שהתוכן של הנתונים לא נפגם או שונה. צריך לכלול לוגיקה לטיפול בקבצים שכבר לא בפורמט יציב.
בקטע הקוד הבא יש דוגמה לאימות של hash:
Kotlin
val hash = calculateHash(stream)
// Store "expectedHash" in a secure location.
if (hash == <var>expectedHash</var>) {
// Work with the content.
}
// Calculating the hash code can take quite a bit of time, so it shouldn't
// be done on the main thread.
suspend fun calculateHash(stream: InputStream): String {
return withContext(Dispatchers.IO) {
val digest = MessageDigest.getInstance("SHA-512")
val digestStream = DigestInputStream(stream, digest)
while (digestStream.read() != -1) {
// The DigestInputStream does the work; nothing for us to do.
}
digest.digest().joinToString(":") { "%02x".format(it) }
}
}
Java
Executor threadPoolExecutor = Executors.newFixedThreadPool(4);
private interface HashCallback {
void onHashCalculated(@Nullable String hash);
}
boolean hashRunning = calculateHash(inputStream, threadPoolExecutor, hash -> {
if (Objects.equals(hash, <var>expectedHash</var>)) {
// Work with the content.
}
});
if (!hashRunning) {
// There was an error setting up the hash function.
}
private boolean calculateHash(@NonNull InputStream stream,
@NonNull Executor executor,
@NonNull HashCallback hashCallback) {
final MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-512");
} catch (NoSuchAlgorithmException nsa) {
return false;
}
// Calculating the hash code can take quite a bit of time, so it shouldn't
// be done on the main thread.
executor.execute(() -> {
String hash;
try (DigestInputStream digestStream =
new DigestInputStream(stream, digest)) {
while (digestStream.read() != -1) {
// The DigestInputStream does the work; nothing for us to do.
}
StringBuilder builder = new StringBuilder();
for (byte aByte : digest.digest()) {
builder.append(String.format("%02x", aByte)).append(':');
}
hash = builder.substring(0, builder.length() - 1);
} catch (IOException e) {
hash = null;
}
final String calculatedHash = hash;
runOnUiThread(() -> hashCallback.onHashCalculated(calculatedHash));
});
return true;
}
שימוש באחסון פנימי לנתוני מטמון רגישים
כדי לספק גישה מהירה יותר לנתוני האפליקציה, צריך לאחסן אותם במטמון של המכשיר. במטמון בגודל של עד 1MB, משתמשים ב-getCacheDir(). במטמון בגודל של יותר מ-1MB, משתמשים ב-getExternalCacheDir(). בשתי השיטות מקבלים את האובייקט File שמכיל את הנתונים במטמון של האפליקציה.
ספריית המטמון הפנימית (שמסופקת על ידי getCacheDir()) היא פרטית לאפליקציה שלכם, אבל ספריית המטמון החיצונית לא.
בקטע הקוד הבא מוצג איך לשמור במטמון קובץ שהאפליקציה הורידה לאחרונה:
Kotlin
val cacheFile = File(myDownloadedFileUri).let { fileToCache ->
File(cacheDir.path, fileToCache.name)
}
Java
File cacheDir = getCacheDir();
File fileToCache = new File(myDownloadedFileUri);
String fileToCacheName = fileToCache.getName();
File cacheFile = new File(cacheDir.getPath(), fileToCacheName);
הערה: אם משתמשים ב-getExternalCacheDir() כדי למקם את מטמון האפליקציה בנפח אחסון משותף, יכול להיות שהמשתמש יוציא את המדיה שמכילה את האחסון הזה בזמן שהאפליקציה פועלת. צריך לכלול לוגיקה לטיפול תקין במצב של אי מציאה במטמון שנגרם מהתנהגות המשתמש.
זהירות: לא נאכפת אבטחה על קבצים בספריית המטמון החיצונית. לכן, כל אפליקציה שמיועדת ל-Android 10 (רמת API 29) או לגרסאות קודמות, ושיש לה הרשאה WRITE_EXTERNAL_STORAGE, יכולה לגשת לתוכן של המטמון הזה.
מידע שקשור לנושא: סקירה כללית על אחסון נתונים וקבצים
שימוש ב-SharedPreferences במצב פרטי
כשמשתמשים ב-getSharedPreferences() כדי ליצור אובייקטים של SharedPreferences באפליקציה או לגשת אליהם, צריך להשתמש ב-MODE_PRIVATE. כך רק האפליקציה יכולה לגשת למידע בקובץ ההעדפות המשותפות.
אם רוצים לשתף נתונים בין אפליקציות, לא משתמשים באובייקטים SharedPreferences. במקום זאת, פועלים לפי השלבים לשיתוף נתונים בצורה מאובטחת בין אפליקציות.
מידע קשור:
עדכון שוטף של השירותים ויחסי התלות
רוב האפליקציות משתמשות בספריות חיצוניות ובמידע על מערכת המכשיר כדי לבצע משימות מיוחדות. כשמקפידים לעדכן את התלות של האפליקציה, משפרים את האבטחה של נקודות התקשורת האלה.
בדיקה של ספק האבטחה של Google Play Services
הערה: הקטע הזה רלוונטי רק לאפליקציות שמטרגטות מכשירים שמותקנים בהם שירותי Google Play.
אם האפליקציה שלכם משתמשת ב-Google Play Services, צריך לוודא שהיא מעודכנת במכשיר שבו היא מותקנת. צריך לבצע את הבדיקה באופן אסינכרוני, מחוץ לשרשור UI. אם המכשיר לא מעודכן, צריך להפעיל שגיאת הרשאה.
כדי לבדוק אם Google Play Services מעודכן במכשיר שבו האפליקציה מותקנת, פועלים לפי השלבים במדריך בנושא עדכון ספק האבטחה כדי להגן מפני ניצול לרעה של SSL.
מידע קשור:
עדכון כל התלויות של האפליקציה
לפני שמפיצים את האפליקציה, חשוב לוודא שכל הספריות, ערכות ה-SDK ויחסי התלות האחרים מעודכנים:
- כדי לעדכן תלות מהדומיין הנוכחי, כמו Android SDK, משתמשים בכלי העדכון שנמצאים ב-Android Studio, כמו SDK Manager.
- במקרה של יחסי תלות בצד שלישי, צריך לבדוק את האתרים של הספריות שבהן האפליקציה משתמשת, ולהתקין עדכונים ותיקוני אבטחה זמינים.
מידע קשור: הוספה של תלות ב-build
מידע נוסף
כדי לקבל מידע נוסף על שיפור האבטחה באפליקציה, אפשר לעיין במקורות המידע הבאים:
- רשימת משימות לבדיקת אבטחה של אפליקציות ליבה
- תוכנית לשיפור אבטחת אפליקציות
- הערוץ של Android Developers ב-YouTube
- Android אישור מוגן: שיפור האבטחה של עסקאות