Uygulama güvenliği en iyi uygulamaları

Uygulamanızı daha güvenli hale getirerek kullanıcı güvenini ve cihaz bütünlüğünü korumaya yardımcı olursunuz.

Bu sayfada, uygulamanızın güvenliği üzerinde önemli ve olumlu etkiye sahip olan çeşitli en iyi uygulamalar sunulmaktadır.

Güvenli iletişimi zorunlu kılma

Uygulamanız ile diğer uygulamalar veya uygulamanız ile bir web sitesi arasında gönderip aldığınız verileri teminat altına alarak uygulamanızın kararlılığını iyileştirir ve gönderip aldığınız verileri korursunuz.

Uygulamalar arasındaki iletişimi koruyun

Uygulamalar arasında daha güvenli bir şekilde iletişim kurmak için uygulama seçici, imzaya dayalı izinler ve dışa aktarılmayan içerik sağlayıcılarla dolaylı intent'leri kullanın.

Uygulama seçici göster

Dolaylı bir intent, kullanıcının cihazında en az iki olası uygulamayı başlatabiliyorsa açık bir şekilde bir uygulama seçici gösterin. Bu etkileşim stratejisi, kullanıcıların hassas bilgileri güvendikleri bir uygulamaya aktarmalarına olanak tanır.

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

    val chooser = resources.getString(R.string.chooser_title).let { title ->
        Intent.createChooser(intent, title)
    }
    startActivity(chooser)
} 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."

    String title = getResources().getString(R.string.chooser_title);
    Intent chooser = Intent.createChooser(intent, title);
    startActivity(chooser);
} else if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

İlgili bilgiler:

İmza tabanlı izinler uygulama

Kontrol ettiğiniz veya sahibi olduğunuz iki uygulama arasında veri paylaşırken imzaya dayalı izinleri kullanın. Bu izinler kullanıcının onayı gerektirmez. Bunun yerine, verilere erişen uygulamaların aynı imzalama anahtarı kullanılarak imzalanıp imzalanmadığını kontrol eder. Bu nedenle, bu izinler daha kolay ve güvenli bir kullanıcı deneyimi sunar.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <permission android:name="my_custom_permission_name"
                android:protectionLevel="signature" />

İlgili bilgiler:

Uygulamanızın içerik sağlayıcılarına erişime izin verme

Uygulamanızdan, sahibi olmadığınız farklı bir uygulamaya veri göndermeyi amaçlamıyorsanız, diğer geliştiricilerin uygulamalarının uygulamanızın ContentProvider nesnelerine erişmesine açıkça izin vermeyin. Bu ayar, uygulamanız Android 4.1.1 (API düzeyi 16) veya önceki sürümleri çalıştıran cihazlara yüklenebiliyorsa özellikle önemlidir. <provider> öğesinin android:exported özelliği, Android'in bu sürümlerinde varsayılan olarak true olmalıdır.

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

Hassas bilgileri göstermeden önce kimlik bilgilerini isteyin

Uygulamanızdaki hassas bilgilere veya premium içeriğe erişebilmeleri için kullanıcılardan kimlik bilgileri isterken bir PIN/şifre/desen veya yüz tanıma ya da parmak izi tanıma gibi biyometrik kimlik bilgisi isteyin.

Biyometrik kimlik bilgileri isteme hakkında daha fazla bilgi edinmek için biyometrik kimlik doğrulama rehberine göz atın.

Ağ güvenlik önlemleri uygulama

Aşağıdaki bölümlerde, uygulamanızın ağ güvenliğini nasıl iyileştirebileceğiniz açıklanmaktadır.

TLS trafiğini kullan

Uygulamanız, tanınmış, güvenilir bir sertifika yetkilisi (CA) tarafından yayınlanmış sertifikası olan bir web sunucusuyla iletişim kuruyorsa aşağıdaki gibi bir HTTPS isteği kullanın:

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();

Ağ güvenliği yapılandırması ekleme

Uygulamanız yeni veya özel CA'lar kullanıyorsa ağınızın güvenlik ayarlarını bir yapılandırma dosyasında belirtebilirsiniz. Bu işlem, herhangi bir uygulama kodunu değiştirmeden yapılandırmayı oluşturmanıza olanak tanır.

Uygulamanıza bir ağ güvenliği yapılandırma dosyası eklemek için şu adımları izleyin:

  1. Uygulamanızın manifest dosyasında yapılandırmayı bildirin:
  2. <manifest ... >
        <application
            android:networkSecurityConfig="@xml/network_security_config"
            ... >
            <!-- Place child elements of <application> element here. -->
        </application>
    </manifest>
    
  3. res/xml/network_security_config.xml konumunda bulunan bir XML kaynak dosyası ekleyin.

    Belirli alanlara yönelik tüm trafiğin HTTPS kullanması gerektiğini belirtmek için açık metni devre dışı bırakın:

    <network-security-config>
        <domain-config cleartextTrafficPermitted="false">
            <domain includeSubdomains="true">secure.example.com</domain>
            ...
        </domain-config>
    </network-security-config>
    

    Geliştirme süreci sırasında, kullanıcı tarafından yüklenen sertifikalara açıkça izin vermek için <debug-overrides> öğesini kullanabilirsiniz. Bu öğe, hata ayıklama ve test sırasında uygulamanın sürüm yapılandırmasını etkilemeden uygulamanızın güvenlik açısından kritik seçeneklerini geçersiz kılar. Aşağıdaki snippet'te bu öğenin, uygulamanızın ağ güvenliği yapılandırma XML dosyasında nasıl tanımlanacağı gösterilmektedir:

    <network-security-config>
        <debug-overrides>
            <trust-anchors>
                <certificates src="user" />
            </trust-anchors>
        </debug-overrides>
    </network-security-config>
    

İlgili bilgiler: Ağ güvenliği yapılandırması

Kendi güven yöneticinizi oluşturma

TLS denetleyiciniz her sertifikayı kabul etmemelidir. Kullanım alanınız için aşağıdaki koşullardan biri geçerliyse bir güven yöneticisi oluşturmanız ve tüm TLS uyarılarını işlemeniz gerekebilir:

  • Yeni veya özel bir CA tarafından imzalanmış sertifikası olan bir web sunucusuyla iletişim kuruyorsunuz.
  • Kullandığınız cihaz bu CA'ya güvenmiyor.
  • Ağ güvenliği yapılandırması kullanamazsınız.

Bu adımların nasıl tamamlanacağı hakkında daha fazla bilgi edinmek için bilinmeyen bir sertifika yetkilisini ele alma hakkındaki tartışmaya bakın.

İlgili bilgiler:

WebView nesnelerini dikkatli kullanın

Uygulamanızdaki WebView nesneleri, kullanıcıların kontrolünüz dışındaki sitelere gitmesine izin vermemelidir. Mümkün olduğunda uygulamanızın WebView nesneleri tarafından yüklenen içeriği kısıtlamak için bir izin verilenler listesi kullanın.

Ayrıca, uygulamanızın WebView nesnelerindeki içeriği tamamen kontrol edip güvenmediğiniz sürece hiçbir zaman JavaScript arayüz desteğini etkinleştirmeyin.

HTML mesajı kanallarını kullanma

Uygulamanızın, Android 6.0 (API düzeyi 23) ve sonraki sürümleri çalıştıran cihazlarda JavaScript arayüz desteğini kullanması gerekiyorsa bir web sitesi ile uygulamanız arasında iletişim kurmak yerine aşağıdaki kod snippet'inde gösterildiği gibi HTML mesaj kanallarını kullanın:

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

İlgili bilgiler:

Doğru izinleri sağlayın

Yalnızca uygulamanızın düzgün çalışması için gereken minimum sayıda izni isteyin. Mümkün olduğunda, uygulamanız artık ihtiyaç duymadığında izinlerden vazgeçin.

İzinleri ertelemek için intent'leri kullanma

Mümkün olduğunda, uygulamanıza başka bir uygulamada tamamlanabilecek bir işlemi tamamlamak için izin eklemeyin. Bunun yerine, isteği zaten gerekli izne sahip olan farklı bir uygulamaya ertelemek için intent kullanın.

Aşağıdaki örnekte, READ_CONTACTS ve WRITE_CONTACTS izinleri istemek yerine kullanıcıları kişiler uygulamasına yönlendirmek için nasıl niyet kullanılacağı gösterilmektedir:

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

Ayrıca, uygulamanızın depolama alanına erişme veya dosya seçme gibi dosyaya dayalı G/Ç işlemleri yapması gerekiyorsa sistem işlemleri uygulamanız adına tamamlayabileceğinden özel izinlere ihtiyacı yoktur. Daha da iyisi, bir kullanıcı belirli bir URI'daki içeriği seçtikten sonra, çağıran uygulamaya seçilen kaynak için izin verilir.

İlgili bilgiler:

Verileri uygulamalar arasında güvenle paylaşın

Uygulamanızın içeriğini diğer uygulamalarla daha güvenli bir şekilde paylaşmak için aşağıdaki en iyi uygulamaları izleyin:

Aşağıdaki kod snippet'inde, bir uygulamanın PDF dosyasını ayrı bir PDF görüntüleyici uygulamasında görüntülemek için URI izni işaretlerinin ve içerik sağlayıcı izinlerinin nasıl kullanılacağı gösterilmektedir:

Kotlin

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

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("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);
}

Not: Yazılabilir uygulama ana dizininden dosya yürütmek bir W^X ihlalidir. Bu nedenle, Android 10 (API düzeyi 29) ve sonraki sürümleri hedefleyen güvenilmeyen uygulamalar uygulamanın ana dizinindeki dosyalarda exec() çağıramaz, yalnızca uygulamanın APK dosyasına yerleştirilmiş ikili kod için çağrıda bulunamaz. Ayrıca, Android 10 ve sonraki sürümleri hedefleyen uygulamalar belleklerinde dlopen() ile açılan dosyalardaki yürütülebilir kodları değiştiremez. Buna, metin konumu içeren tüm paylaşılan nesne (.so) dosyaları dahildir.

İlgili bilgiler: android:grantUriPermissions

Verileri güvenli şekilde depolayın

Uygulamanız hassas kullanıcı bilgilerine erişmeyi gerektirse de kullanıcılar, yalnızca verilerinizi düzgün bir şekilde koruduğunuza güvendiklerinde uygulamanızın verilerine erişmesine izin verirler.

Gizli verileri dahili depolamada depolayın

Tüm özel kullanıcı verilerini, uygulama başına korumalı alana alınan cihazın dahili depolamasında depolayın. Uygulamanızın bu dosyaları görüntülemek için izin istemesi gerekmez ve diğer uygulamalar dosyalara erişemez. Ek bir güvenlik önlemi olarak, kullanıcı bir uygulamayı kaldırdığında cihaz, uygulamanın dahili depolama alanına kaydettiği tüm dosyaları siler.

Not: Sakladığınız veriler özellikle hassas veya gizliyse File nesneleri yerine Güvenlik kitaplığından sunulan EncryptedFile nesneleriyle çalışmayı düşünün.

Aşağıdaki kod snippet'i, verileri depolama alanına yazmanın bir yolunu göstermektedir:

Kotlin

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

// Create a file with this name or replace an entire existing file
// that has the same name. Note that you cannot append to an existing file,
// and the filename cannot contain path separators.
val fileToWrite = "my_sensitive_data.txt"
val encryptedFile = EncryptedFile.Builder(
    File(DIRECTORY, fileToWrite),
    applicationContext,
    mainKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

val fileContent = "MY SUPER-SECRET INFORMATION"
        .toByteArray(StandardCharsets.UTF_8)
encryptedFile.openFileOutput().apply {
    write(fileContent)
    flush()
    close()
}

Java

Context context = getApplicationContext();

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC;
String mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec);

// Create a file with this name or replace an entire existing file
// that has the same name. Note that you cannot append to an existing file,
// and the filename cannot contain path separators.
String fileToWrite = "my_sensitive_data.txt";
EncryptedFile encryptedFile = new EncryptedFile.Builder(
        new File(DIRECTORY, fileToWrite),
        context,
        mainKeyAlias,
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build();

byte[] fileContent = "MY SUPER-SECRET INFORMATION"
        .getBytes(StandardCharsets.UTF_8);
OutputStream outputStream = encryptedFile.openFileOutput();
outputStream.write(fileContent);
outputStream.flush();
outputStream.close();

Aşağıdaki kod snippet'i, depolama alanından verileri okuyan ters işlemi göstermektedir:

Kotlin

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

val fileToRead = "my_sensitive_data.txt"
val encryptedFile = EncryptedFile.Builder(
    File(DIRECTORY, fileToRead),
    applicationContext,
    mainKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

val inputStream = encryptedFile.openFileInput()
val byteArrayOutputStream = ByteArrayOutputStream()
var nextByte: Int = inputStream.read()
while (nextByte != -1) {
    byteArrayOutputStream.write(nextByte)
    nextByte = inputStream.read()
}

val plaintext: ByteArray = byteArrayOutputStream.toByteArray()

Java

Context context = getApplicationContext();

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC;
String mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec);

String fileToRead = "my_sensitive_data.txt";
EncryptedFile encryptedFile = new EncryptedFile.Builder(
        new File(DIRECTORY, fileToRead),
        context,
        mainKeyAlias,
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build();

InputStream inputStream = encryptedFile.openFileInput();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int nextByte = inputStream.read();
while (nextByte != -1) {
    byteArrayOutputStream.write(nextByte);
    nextByte = inputStream.read();
}

byte[] plaintext = byteArrayOutputStream.toByteArray();

İlgili bilgiler:

Kullanım alanına göre verileri harici depolamada depolayın

Uygulamanıza özel büyük, hassas olmayan dosyaların yanı sıra uygulamanızın diğer uygulamalarla paylaştığı dosyalar için harici depolama kullanın. Kullandığınız API'ler, uygulamanızın uygulamaya özel dosyalara veya paylaşılan dosyalara erişmek için tasarlanmış olup olmamasına bağlı olarak farklılık gösterir.

Bir dosya gizli veya hassas bilgiler içermiyorsa ancak kullanıcıya yalnızca uygulamanızda değer sağlıyorsa dosyayı harici depolamadaki uygulamaya özel bir dizinde depolayın.

Uygulamanızın diğer uygulamalara değer sağlayan bir dosyaya erişmesi veya bu dosyayı depolaması gerekiyorsa kullanım alanınıza bağlı olarak aşağıdaki API'lerden birini kullanın:

Depolama hacminin kullanılabilirliğini kontrol et

Uygulamanız çıkarılabilir bir harici depolama cihazıyla etkileşimde bulunursa, uygulamanız erişmeye çalışırken kullanıcının depolama cihazını kaldırabileceğini unutmayın. Depolama cihazının kullanılabilir olduğunu doğrulama mantığını ekleyin.

Verilerin geçerliliğini kontrol edin

Uygulamanız harici depolamadan veri kullanıyorsa verilerin içeriğinin bozulmadığından veya değiştirilmediğinden emin olun. Artık kararlı biçimde olmayan dosyaları işlemek için bir mantık ekleyin.

Aşağıdaki kod snippet'i, bir karma doğrulayıcı örneği içerir:

Kotlin

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

Java

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

Önbellek dosyalarında yalnızca hassas olmayan verileri depolayın

Hassas olmayan uygulama verilerine daha hızlı erişim sağlamak için bu verileri cihazın önbelleğinde depolayın. 1 MB'tan büyük önbellekler için getExternalCacheDir() işlevini kullanın. 1 MB veya daha küçük önbellekler için getCacheDir() kullanın. Her iki yöntem de size uygulamanızın önbelleğe alınan verilerini içeren File nesnesini sağlar.

Aşağıdaki kod snippet'i, uygulamanızın yakın zamanda indirdiği bir dosyanın nasıl önbelleğe alınacağını gösterir:

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

Not: Uygulamanızın önbelleğini paylaşılan depolama alanına yerleştirmek için getExternalCacheDir() kullanırsanız kullanıcı, uygulamanız çalışırken bu depolama alanını içeren medyayı çıkarabilir. Bu kullanıcı davranışının neden olduğu önbellek eksikliğini düzgün bir şekilde ele almak için bir mantık ekleyin.

Dikkat: Bu dosyalarda zorunlu kılınan bir güvenlik yoktur. Bu nedenle, Android 10 (API düzeyi 29) veya önceki sürümleri hedefleyen ve WRITE_EXTERNAL_STORAGE iznine sahip olan tüm uygulamalar bu önbelleğin içeriğine erişebilir.

İlgili bilgiler: Veri ve dosya depolamaya genel bakış

SharedPreferences'ı gizli modda kullanın

Uygulamanızın SharedPreferences nesnelerini oluşturmak veya bu nesnelere erişmek için getSharedPreferences() kullanırken MODE_PRIVATE kullanın. Bu şekilde, paylaşılan tercihler dosyasındaki bilgilere yalnızca uygulamanız erişebilir.

Uygulamalar arasında veri paylaşmak istiyorsanız SharedPreferences nesneleri kullanmayın. Bunun yerine, verileri uygulamalar arasında güvenli bir şekilde paylaşma adımlarını uygulayın.

Güvenlik kitaplığında, SharedPreferences sınıfını sarmalayan ve anahtarlar ile değerleri otomatik olarak şifreleyen EncryptedSharedPreferences sınıfı da bulunmaktadır.

İlgili bilgiler:

Hizmetleri ve bağımlılıkları güncel tutmak

Çoğu uygulama, özel görevleri tamamlamak için harici kitaplıkları ve cihaz sistem bilgilerini kullanır. Uygulamanızın bağımlılıklarını güncel tutarak bu iletişim noktalarını daha güvenli hale getirebilirsiniz.

Google Play Hizmetleri güvenlik sağlayıcısını kontrol etme

Not: Bu bölüm yalnızca Google Play Hizmetleri yüklü cihazları hedefleyen uygulamalar için geçerlidir.

Uygulamanız Google Play Hizmetleri'ni kullanıyorsa uygulamanızın yüklü olduğu cihazda güncellendiğinden emin olun. Kontrolü kullanıcı arayüzü iş parçacığının dışında eşzamansız olarak gerçekleştirin. Cihaz güncel değilse bir yetkilendirme hatası tetikleyin.

Uygulamanızın yüklü olduğu cihazda Google Play Hizmetleri'nin güncel olup olmadığını belirlemek için SSL istismarlarına karşı koruma sağlamak için güvenlik sağlayıcınızı güncelleme ile ilgili kılavuzdaki adımları uygulayın.

İlgili bilgiler:

Tüm uygulama bağımlılıklarını güncelleyin

Uygulamanızı dağıtmadan önce tüm kitaplıkların, SDK'ların ve diğer bağımlılıkların güncel olduğundan emin olun:

  • Android SDK gibi birinci taraf bağımlılıklar için Android Studio'da bulunan SDK Yöneticisi gibi güncelleme araçlarını kullanın.
  • Üçüncü taraf bağımlılıkları için uygulamanızın kullandığı kitaplıkların web sitelerini kontrol edip mevcut güncellemeleri ve güvenlik yamalarını yükleyin.

İlgili bilgi: Bağımlılık oluşturma

Daha fazla bilgi

Uygulamanızı daha güvenli hale getirme hakkında daha fazla bilgi edinmek için aşağıdaki kaynaklara göz atın: