امنیت برنامه خود را بهبود بخشید، امنیت برنامه خود را بهبود بخشید، امنیت برنامه خود را بهبود بخشید

با ایمن‌تر کردن برنامه خود، به حفظ اعتماد کاربر و یکپارچگی دستگاه کمک می‌کنید.

این صفحه چندین شیوه برتر را ارائه می‌دهد که تأثیر مثبت و قابل توجهی بر امنیت برنامه شما دارند.

برقراری ارتباط امن را تقویت کنید

وقتی از داده‌هایی که بین برنامه خود و سایر برنامه‌ها یا بین برنامه خود و یک وب‌سایت رد و بدل می‌کنید، محافظت می‌کنید، پایداری برنامه خود را بهبود می‌بخشید و از داده‌هایی که ارسال و دریافت می‌کنید محافظت می‌کنید.

محافظت از ارتباط بین برنامه‌ها

برای برقراری ارتباط امن‌تر بین برنامه‌ها، از اهداف ضمنی با انتخابگر برنامه، مجوزهای مبتنی بر امضا و ارائه‌دهندگان محتوای غیر صادر شده استفاده کنید.

نمایش انتخابگر برنامه

اگر یک هدف ضمنی بتواند حداقل دو برنامه ممکن را روی دستگاه کاربر اجرا کند، به صراحت یک انتخابگر برنامه را نشان می‌دهد. این استراتژی تعامل به کاربران اجازه می‌دهد اطلاعات حساس را به برنامه‌ای که به آن اعتماد دارند منتقل کنند.

کاتلین

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."

    val chooser = resources.getString(R.string.chooser_title).let { title ->
        Intent.createChooser(intent, title)
    }
    startActivity(chooser)
} else if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
}

جاوا

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."

    String title = getResources().getString(R.string.chooser_title);
    Intent chooser = Intent.createChooser(intent, title);
    startActivity(chooser);
} 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 برنامه خود را ممنوع کنید. این تنظیم به ویژه در صورتی مهم است که برنامه شما بتواند روی دستگاه‌هایی که اندروید ۴.۱.۱ (سطح API ۱۶) یا پایین‌تر را اجرا می‌کنند نصب شود، زیرا ویژگی android:exported عنصر <provider> به طور پیش‌فرض در این نسخه‌های اندروید true است.

<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 مانند زیر استفاده کنید:

کاتلین

val url = URL("https://www.google.com")
val urlConnection = url.openConnection() as HttpsURLConnection
urlConnection.connect()
urlConnection.inputStream.use {
    ...
}

جاوا

URL url = new URL("https://www.google.com");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.connect();
InputStream in = urlConnection.getInputStream();

اضافه کردن پیکربندی امنیت شبکه

اگر برنامه شما از CA های جدید یا سفارشی استفاده می‌کند، می‌توانید تنظیمات امنیتی شبکه خود را در یک فایل پیکربندی اعلام کنید. این فرآیند به شما امکان می‌دهد پیکربندی را بدون تغییر هیچ کد برنامه‌ای ایجاد کنید.

برای افزودن فایل پیکربندی امنیت شبکه به برنامه خود، این مراحل را دنبال کنید:

  1. پیکربندی را در مانیفست برنامه خود اعلام کنید:
  2. <manifest ... >
        <application
            android:networkSecurityConfig="@xml/network_security_config"
            ... >
            <!-- Place child elements of <application> element here. -->
        </application>
    </manifest>
  3. یک فایل منبع XML، واقع در res/xml/network_security_config.xml اضافه کنید.

    با غیرفعال کردن clear-text، مشخص کنید که تمام ترافیک به دامنه‌های خاص باید از HTTPS استفاده کنند:

    <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>

مطالب مرتبط: پیکربندی امنیت شبکه

مدیر اعتماد خودتان را ایجاد کنید

بررسی‌کننده‌ی TLS شما نباید هر گواهی‌نامه‌ای را بپذیرد. اگر یکی از شرایط زیر در مورد استفاده‌ی شما صدق کند، ممکن است لازم باشد یک مدیر اعتماد راه‌اندازی کنید و تمام هشدارهای TLS که رخ می‌دهد را مدیریت کنید:

  • شما در حال برقراری ارتباط با یک وب سرور هستید که دارای گواهی امضا شده توسط یک CA جدید یا سفارشی است.
  • آن مرجع صدور گواهی (CA) مورد اعتماد دستگاهی که شما استفاده می‌کنید، نیست.
  • شما نمی‌توانید از پیکربندی امنیت شبکه استفاده کنید.

برای کسب اطلاعات بیشتر در مورد نحوه انجام این مراحل، به بحث مربوط به مدیریت یک مرجع صدور گواهی ناشناخته مراجعه کنید.

اطلاعات مرتبط:

از اشیاء WebView با دقت استفاده کنید

اشیاء WebView در برنامه شما نباید به کاربران اجازه دهند به سایت‌هایی که خارج از کنترل شما هستند، هدایت شوند. هر زمان که ممکن بود، از یک لیست مجاز برای محدود کردن محتوای بارگذاری شده توسط اشیاء WebView برنامه خود استفاده کنید.

علاوه بر این، هرگز پشتیبانی از رابط جاوا اسکریپت را فعال نکنید، مگر اینکه محتوای موجود در اشیاء WebView برنامه خود را کاملاً کنترل و به آن اعتماد داشته باشید.

از کانال‌های پیام HTML استفاده کنید

اگر برنامه شما باید از پشتیبانی رابط جاوا اسکریپت در دستگاه‌هایی که اندروید ۶.۰ (سطح API ۲۳) و بالاتر دارند استفاده کند، به جای ارتباط بین وب‌سایت و برنامه خود، از کانال‌های پیام HTML استفاده کنید، همانطور که در قطعه کد زیر نشان داده شده است:

کاتلین

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"))

جاوا

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 را نشان می‌دهد:

کاتلین

// 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)
    }
}

جاوا

// 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 ، به کلاینت‌ها دسترسی یک‌باره به داده‌ها را ارائه دهید.
  • هنگام اشتراک‌گذاری داده‌ها، از URLهای content:// استفاده کنید، نه file:// . نمونه‌هایی از FileProvider این کار را برای شما انجام می‌دهند.

قطعه کد زیر نحوه استفاده از پرچم‌های اعطای مجوز URI و مجوزهای ارائه‌دهنده محتوا را برای نمایش فایل PDF یک برنامه در یک برنامه نمایش PDF جداگانه نشان می‌دهد:

کاتلین

// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse("content://com.example/personal-info.pdf")

    // This flag gives the started app read access to the file.
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}.also { intent ->
    // Make sure that the user has a PDF viewer app installed on their device.
    intent.resolveActivity(packageManager)?.run {
        startActivity(intent)
    }
}

جاوا

// 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("content://com.example/personal-info.pdf"));

// This flag gives the started app read access to the file.
viewPdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// Make sure that the user has a PDF viewer app installed on their device.
if (viewPdfIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(viewPdfIntent);
}

توجه: اجرای فایل‌ها از دایرکتوری خانگی برنامه قابل نوشتن، نقض W^X است. به همین دلیل، برنامه‌های غیرقابل اعتماد که اندروید ۱۰ (سطح API ۲۹) و بالاتر را هدف قرار می‌دهند، نمی‌توانند تابع exec() را روی فایل‌های داخل دایرکتوری خانگی برنامه فراخوانی کنند، فقط کد باینری که در فایل APK برنامه تعبیه شده است. علاوه بر این، برنامه‌هایی که اندروید ۱۰ و بالاتر را هدف قرار می‌دهند، نمی‌توانند در حافظه، کد اجرایی فایل‌هایی را که با dlopen() باز شده‌اند، تغییر دهند. این شامل هر فایل شیء مشترک ( .so ) با جابجایی متن می‌شود.

اطلاعات مرتبط: android:grantUriPermissions

داده‌ها را با خیال راحت ذخیره کنید

اگرچه ممکن است برنامه شما نیاز به دسترسی به اطلاعات حساس کاربر داشته باشد، کاربران فقط در صورتی به برنامه شما اجازه دسترسی به داده‌های خود را می‌دهند که به شما اعتماد داشته باشند که از آنها به درستی محافظت می‌کنید.

ذخیره داده‌های خصوصی در حافظه داخلی

تمام داده‌های خصوصی کاربر را در حافظه داخلی دستگاه ذخیره کنید، که برای هر برنامه به صورت ایمن (sandbox) نگهداری می‌شود. برنامه شما نیازی به درخواست مجوز برای مشاهده این فایل‌ها ندارد و سایر برنامه‌ها نمی‌توانند به این فایل‌ها دسترسی داشته باشند. به عنوان یک اقدام امنیتی اضافی، هنگامی که کاربر یک برنامه را حذف نصب می‌کند، دستگاه تمام فایل‌هایی را که برنامه در حافظه داخلی ذخیره کرده بود، حذف می‌کند.

قطعه کد زیر یک روش برای نوشتن داده‌ها در حافظه داخلی را نشان می‌دهد:

کاتلین

// 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)
}

جاوا

// 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.
}

قطعه کد زیر عملیات معکوس، یعنی خواندن داده‌ها از حافظه داخلی را نشان می‌دهد:

کاتلین

val FILE_NAME = "sensitive_info.txt"
val contents = File(filesDir, FILE_NAME).bufferedReader().useLines { lines ->
    lines.fold("") { working, line ->
        "$working\n$line"
    }
}

جاوا

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 های زیر استفاده کنید:

بررسی در دسترس بودن حجم ذخیره‌سازی

اگر برنامه شما با یک دستگاه ذخیره‌سازی خارجی قابل جابجایی تعامل دارد، به خاطر داشته باشید که ممکن است کاربر در حین تلاش برنامه برای دسترسی به دستگاه ذخیره‌سازی، آن را حذف کند. منطقی را برای تأیید در دسترس بودن دستگاه ذخیره‌سازی در نظر بگیرید.

بررسی اعتبار داده‌ها

اگر برنامه شما از داده‌های حافظه خارجی استفاده می‌کند، مطمئن شوید که محتوای داده‌ها خراب یا تغییر نکرده باشد. منطقی را برای مدیریت فایل‌هایی که دیگر فرمت پایداری ندارند، در نظر بگیرید.

قطعه کد زیر شامل نمونه‌ای از یک تأییدکننده هش است:

کاتلین

val hash = calculateHash(stream)
// Store "expectedHash" in a secure location.
if (hash == expectedHash) {
    // 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) }
    }
}

جاوا

Executor threadPoolExecutor = Executors.newFixedThreadPool(4);
private interface HashCallback {
    void onHashCalculated(@Nullable String hash);
}

boolean hashRunning = calculateHash(inputStream, threadPoolExecutor, hash -> {
    if (Objects.equals(hash, expectedHash)) {
        // 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;
}

فقط داده‌های غیر حساس را در فایل‌های حافظه پنهان ذخیره کنید

برای دسترسی سریع‌تر به داده‌های غیرحساس برنامه، آن‌ها را در حافظه پنهان دستگاه ذخیره کنید. برای حافظه‌های پنهان بزرگتر از ۱ مگابایت، از getExternalCacheDir() استفاده کنید. برای حافظه‌های پنهان ۱ مگابایت یا کمتر، از getCacheDir() استفاده کنید. هر دو روش، شیء File را که شامل داده‌های ذخیره شده برنامه شما است، در اختیار شما قرار می‌دهند.

قطعه کد زیر نحوه‌ی ذخیره‌ی فایلی که برنامه‌ی شما اخیراً دانلود کرده است را نشان می‌دهد:

کاتلین

val cacheFile = File(myDownloadedFileUri).let { fileToCache ->
    File(cacheDir.path, fileToCache.name)
}

جاوا

File cacheDir = getCacheDir();
File fileToCache = new File(myDownloadedFileUri);
String fileToCacheName = fileToCache.getName();
File cacheFile = new File(cacheDir.getPath(), fileToCacheName);

نکته: اگر از getExternalCacheDir() برای قرار دادن حافظه پنهان برنامه خود در فضای ذخیره‌سازی مشترک استفاده کنید، ممکن است کاربر هنگام اجرای برنامه، رسانه‌ای که حاوی این فضای ذخیره‌سازی است را حذف کند. منطقی را برای مدیریت مناسب عدم نمایش حافظه پنهان که این رفتار کاربر ایجاد می‌کند، در نظر بگیرید.

احتیاط: هیچ گونه امنیتی روی این فایل‌ها اعمال نشده است. بنابراین، هر برنامه‌ای که اندروید ۱۰ (سطح API ۲۹) یا پایین‌تر را هدف قرار می‌دهد و مجوز WRITE_EXTERNAL_STORAGE را دارد، می‌تواند به محتوای این حافظه پنهان دسترسی داشته باشد.

اطلاعات مرتبط: مروری بر ذخیره‌سازی داده‌ها و فایل‌ها

استفاده از SharedPreferences در حالت خصوصی

هنگام استفاده از getSharedPreferences() برای ایجاد یا دسترسی به اشیاء SharedPreferences برنامه خود، از MODE_PRIVATE استفاده کنید. به این ترتیب، فقط برنامه شما می‌تواند به اطلاعات درون فایل تنظیمات اشتراکی دسترسی داشته باشد.

اگر می‌خواهید داده‌ها را بین برنامه‌ها به اشتراک بگذارید، از اشیاء SharedPreferences استفاده نکنید. در عوض، مراحل اشتراک‌گذاری ایمن داده‌ها بین برنامه‌ها را دنبال کنید.

اطلاعات مرتبط:

سرویس‌ها و وابستگی‌ها را به‌روز نگه دارید

اکثر برنامه‌ها از کتابخانه‌های خارجی و اطلاعات سیستم دستگاه برای انجام وظایف تخصصی استفاده می‌کنند. با به‌روز نگه داشتن وابستگی‌های برنامه خود، این نقاط ارتباطی را ایمن‌تر می‌کنید.

ارائه دهنده امنیت خدمات Google Play را بررسی کنید

توجه: این بخش فقط برای برنامه‌هایی اعمال می‌شود که دستگاه‌هایی را هدف قرار می‌دهند که سرویس‌های Google Play را نصب کرده‌اند.

اگر برنامه شما از سرویس‌های گوگل پلی استفاده می‌کند، مطمئن شوید که در دستگاهی که برنامه شما روی آن نصب شده است، به‌روزرسانی شده است. بررسی را به صورت ناهمگام و خارج از نخ رابط کاربری انجام دهید. اگر دستگاه به‌روز نباشد، خطای مجوزدهی ایجاد می‌شود.

برای تعیین اینکه آیا سرویس‌های گوگل پلی در دستگاهی که برنامه شما روی آن نصب شده است، به‌روز هستند یا خیر، مراحل موجود در راهنمای مربوط به به‌روزرسانی ارائه‌دهنده امنیتی خود برای محافظت در برابر سوءاستفاده‌های SSL را دنبال کنید.

اطلاعات مرتبط:

تمام وابستگی‌های برنامه را به‌روزرسانی کنید

قبل از استقرار برنامه خود، مطمئن شوید که همه کتابخانه‌ها، SDKها و سایر وابستگی‌ها به‌روز هستند:

  • برای وابستگی‌های شخص ثالث، مانند SDK اندروید، از ابزارهای به‌روزرسانی موجود در اندروید استودیو، مانند SDK Manager ، استفاده کنید.
  • برای وابستگی‌های شخص ثالث، وب‌سایت‌های کتابخانه‌هایی که برنامه شما از آنها استفاده می‌کند را بررسی کنید و هرگونه به‌روزرسانی و وصله امنیتی موجود را نصب کنید.

اطلاعات مرتبط: اضافه کردن وابستگی‌های ساخت

اطلاعات بیشتر

برای کسب اطلاعات بیشتر در مورد چگونگی ایمن‌تر کردن برنامه خود، به منابع زیر مراجعه کنید: