App-Sicherheit verbessern

Wenn Sie Ihre App sicherer machen, tragen Sie dazu bei, das Vertrauen der Nutzer und die Geräteintegrität zu wahren.

Auf dieser Seite werden mehrere Best Practices vorgestellt, die sich erheblich positiv auf die Sicherheit Ihrer App auswirken.

Sichere Kommunikation erzwingen

Wenn Sie die Daten schützen, die zwischen Ihrer App und anderen Apps oder zwischen Ihrer App und einer Website ausgetauscht werden, verbessern Sie die Stabilität Ihrer App und schützen die Daten, die Sie senden und empfangen.

Kommunikation zwischen Apps schützen

Um die Kommunikation zwischen Apps sicherer zu gestalten, sollten Sie implizite Intents mit einer App-Auswahl, signaturbasierte Berechtigungen und nicht exportierte Contentanbieter verwenden.

App-Auswahl anzeigen

Wenn durch eine implizite Absicht mindestens zwei mögliche Apps auf dem Gerät eines Nutzers gestartet werden können, muss eine App-Auswahl angezeigt werden. Mit dieser Interaktionsstrategie können Nutzer vertrauliche Informationen an eine App übertragen, der sie vertrauen.

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

Weitere Informationen

Signaturbasierte Berechtigungen anwenden

Wenn Sie Daten zwischen zwei Apps teilen, die Sie kontrollieren oder besitzen, verwenden Sie signaturbasierte Berechtigungen. Für diese Berechtigungen ist keine Nutzerbestätigung erforderlich. Stattdessen wird geprüft, ob die Apps, die auf die Daten zugreifen, mit demselben Signaturschlüssel signiert sind. Diese Berechtigungen bieten daher eine optimierte und sichere Nutzererfahrung.

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

Weitere Informationen :

Zugriff auf die Contentanbieter Ihrer App nicht zulassen

Wenn Sie nicht beabsichtigen, Daten aus Ihrer App an eine andere App zu senden, die Ihnen nicht gehört, müssen Sie den Apps anderer Entwickler den Zugriff auf die ContentProvider-Objekte Ihrer App explizit untersagen. Diese Einstellung ist besonders wichtig, wenn Ihre App auf Geräten mit Android 4.1.1 (API‑Level 16) oder niedriger installiert werden kann, da das Attribut android:exported<provider>true standardmäßig auf diesen Android-Versionen ist.

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

Vor dem Anzeigen vertraulicher Informationen nach Anmeldedaten fragen

Wenn Sie Anmeldedaten von Nutzern anfordern, damit sie in Ihrer App auf vertrauliche Informationen oder Premium-Inhalte zugreifen können, fragen Sie entweder nach einer PIN, einem Passwort oder einem Muster oder nach biometrischen Anmeldedaten wie Gesichtserkennung oder Fingerabdruckerkennung.

Weitere Informationen zum Anfordern biometrischer Anmeldedaten finden Sie im Leitfaden zur biometrischen Authentifizierung.

Netzwerksicherheitsmaßnahmen anwenden

In den folgenden Abschnitten wird beschrieben, wie Sie die Netzwerksicherheit Ihrer App verbessern können.

TLS-Traffic verwenden

Wenn Ihre App mit einem Webserver kommuniziert, der ein Zertifikat von einer bekannten, vertrauenswürdigen Zertifizierungsstelle (CA) hat, verwenden Sie eine HTTPS-Anfrage wie die folgende:

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

Netzwerksicherheitskonfiguration hinzufügen

Wenn Ihre App neue oder benutzerdefinierte Zertifizierungsstellen verwendet, können Sie die Sicherheitseinstellungen Ihres Netzwerks in einer Konfigurationsdatei deklarieren. Mit diesem Verfahren können Sie die Konfiguration erstellen, ohne den App-Code zu ändern.

So fügen Sie Ihrer App eine Datei mit der Netzwerksicherheitskonfiguration hinzu:

  1. Deklarieren Sie die Konfiguration im Manifest Ihrer App:
  2. <manifest ... >
        <application
            android:networkSecurityConfig="@xml/network_security_config"
            ... >
            <!-- Place child elements of <application> element here. -->
        </application>
    </manifest>
  3. Fügen Sie eine XML-Ressourcendatei unter res/xml/network_security_config.xml hinzu.

    Geben Sie an, dass für den gesamten Traffic zu bestimmten Domains HTTPS verwendet werden muss, indem Sie den Klartext deaktivieren:

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

    Während der Entwicklung können Sie das <debug-overrides>-Element verwenden, um explizit vom Nutzer installierte Zertifikate zuzulassen. Dieses Element überschreibt die sicherheitskritischen Optionen Ihrer App während des Debuggens und Testens, ohne die Releasekonfiguration der App zu beeinträchtigen. Das folgende Snippet zeigt, wie Sie dieses Element in der XML-Datei für die Netzwerksicherheitskonfiguration Ihrer App definieren:

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

Zugehörige Informationen : Konfiguration der Netzwerksicherheit

Eigenen Trust Manager erstellen

Ihr TLS-Checker sollte nicht jedes Zertifikat akzeptieren. Möglicherweise müssen Sie einen Trust Manager einrichten und alle TLS-Warnungen behandeln, die auftreten, wenn eine der folgenden Bedingungen auf Ihren Anwendungsfall zutrifft:

  • Sie kommunizieren mit einem Webserver, der ein Zertifikat hat, das von einer neuen oder benutzerdefinierten Zertifizierungsstelle signiert wurde.
  • Die Zertifizierungsstelle wird von dem Gerät, das Sie verwenden, nicht als vertrauenswürdig eingestuft.
  • Sie können keine Netzwerksicherheitskonfiguration verwenden.

Weitere Informationen zum Ausführen dieser Schritte finden Sie im Abschnitt zum Umgang mit einer unbekannten Zertifizierungsstelle.

Weitere Informationen

WebView-Objekte mit Bedacht verwenden

WebView Objekte in Ihrer App dürfen Nutzer nicht zu Websites weiterleiten, die nicht unter Ihrer Kontrolle stehen. Verwenden Sie nach Möglichkeit eine Zulassungsliste, um die von den WebView-Objekten Ihrer App geladenen Inhalte einzuschränken.

Aktivieren Sie außerdem niemals die Unterstützung der JavaScript-Schnittstelle, es sei denn, Sie haben die vollständige Kontrolle über die Inhalte in den WebView-Objekten Ihrer App und vertrauen ihnen.

HTML-Nachrichtenchannels verwenden

Wenn Ihre App die Unterstützung von JavaScript-Schnittstellen auf Geräten mit Android 6.0 (API-Level 23) und höher verwenden muss, verwenden Sie HTML-Nachrichtenkanäle für die Kommunikation zwischen einer Website und Ihrer App, wie im folgenden Code-Snippet gezeigt:

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

Weitere Informationen

Die richtigen Berechtigungen erteilen

Fordern Sie nur die Mindestanzahl an Berechtigungen an, die für die ordnungsgemäße Funktion Ihrer App erforderlich sind. Geben Sie Berechtigungen nach Möglichkeit frei, wenn Ihre App sie nicht mehr benötigt.

Intents zum Aufschieben von Berechtigungen verwenden

Fügen Sie Ihrer App nach Möglichkeit keine Berechtigung hinzu, um eine Aktion auszuführen, die in einer anderen App ausgeführt werden kann. Verwenden Sie stattdessen einen Intent, um die Anfrage an eine andere App zu übertragen, die bereits die erforderliche Berechtigung hat.

Das folgende Beispiel zeigt, wie Sie Nutzer mithilfe einer Absicht zu einer Kontakte-App weiterleiten, anstatt die Berechtigungen READ_CONTACTS und WRITE_CONTACTS anzufordern:

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

Wenn Ihre App dateibasierte E/A-Vorgänge ausführen muss, z. B. auf den Speicher zugreifen oder eine Datei auswählen, sind keine speziellen Berechtigungen erforderlich, da das System die Vorgänge im Namen Ihrer App ausführen kann. Noch besser: Nachdem ein Nutzer Inhalte unter einem bestimmten URI ausgewählt hat, erhält die aufrufende App die Berechtigung für die ausgewählte Ressource.

Weitere Informationen

Daten sicher zwischen Apps teilen

Mit den folgenden Best Practices können Sie die Inhalte Ihrer App sicherer mit anderen Apps teilen:

Das folgende Code-Snippet zeigt, wie Sie URI-Berechtigungsflags und Contentanbieterberechtigungen verwenden, um die PDF-Datei einer App in einer separaten PDF-Viewer-App anzuzeigen:

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

Hinweis : Das Ausführen von Dateien aus dem beschreibbaren App-Home-Verzeichnis ist ein W^X-Verstoß. Aus diesem Grund können nicht vertrauenswürdige Apps, die auf Android 10 (API-Level 29) und höher ausgerichtet sind, exec() nicht für Dateien im Basisverzeichnis der App aufrufen, sondern nur für den Binärcode, der in der APK-Datei einer App eingebettet ist. Außerdem dürfen Apps, die auf Android 10 und höher ausgerichtet sind, im Arbeitsspeicher keinen ausführbaren Code aus Dateien ändern, die mit dlopen() geöffnet wurden. Dazu gehören alle Dateien mit gemeinsam genutzten Objekten (.so) mit Text-Relokationen.

Weitere Informationen : android:grantUriPermissions

Daten sicher speichern

Auch wenn Ihre App möglicherweise Zugriff auf vertrauliche Nutzerinformationen benötigt, gewähren Nutzer Ihrer App nur dann Zugriff auf ihre Daten, wenn sie darauf vertrauen, dass Sie diese angemessen schützen.

Private Daten im internen Speicher speichern

Speichern Sie alle privaten Nutzerdaten im internen Speicher des Geräts, der für jede App in einer Sandbox ausgeführt wird. Ihre App muss keine Berechtigung zum Anzeigen dieser Dateien anfordern und andere Apps können nicht auf die Dateien zugreifen. Als zusätzliche Sicherheitsmaßnahme werden beim Deinstallieren einer App alle Dateien gelöscht, die von der App im internen Speicher gespeichert wurden.

Das folgende Code-Snippet zeigt eine Möglichkeit, Daten in den internen Speicher zu schreiben:

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

Das folgende Code-Snippet zeigt den umgekehrten Vorgang, das Lesen von Daten aus dem internen Speicher:

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

Weitere Informationen

Daten je nach Anwendungsfall in externem Speicher speichern

Verwenden Sie externen Speicher für große, nicht vertrauliche Dateien, die für Ihre App spezifisch sind, sowie für Dateien, die Ihre App mit anderen Apps teilt. Welche APIs Sie verwenden, hängt davon ab, ob Ihre App für den Zugriff auf app-spezifische Dateien oder auf freigegebene Dateien konzipiert ist.

Wenn eine Datei keine privaten oder vertraulichen Informationen enthält, aber nur in Ihrer App für den Nutzer von Nutzen ist, speichern Sie die Datei in einem app-spezifischen Verzeichnis im externen Speicher.

Wenn Ihre App auf eine Datei zugreifen oder eine Datei speichern muss, die für andere Apps von Nutzen ist, verwenden Sie je nach Anwendungsfall eine der folgenden APIs:

Verfügbarkeit des Speichervolumes prüfen

Wenn Ihre App mit einem Wechseldatenträger interagiert, sollten Sie bedenken, dass der Nutzer das Speichermedium entfernen kann, während Ihre App darauf zugreift. Fügen Sie Logik hinzu, um zu prüfen, ob das Speichermedium verfügbar ist.

Gültigkeit von Daten prüfen

Wenn Ihre App Daten aus dem externen Speicher verwendet, achten Sie darauf, dass der Inhalt der Daten nicht beschädigt oder geändert wurde. Logik zum Verarbeiten von Dateien einfügen, die nicht mehr in einem stabilen Format vorliegen.

Das folgende Code-Snippet enthält ein Beispiel für einen Hash-Prüfer:

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

Nur nicht vertrauliche Daten in Cache-Dateien speichern

Um einen schnelleren Zugriff auf nicht sensible App-Daten zu ermöglichen, sollten Sie sie im Cache des Geräts speichern. Verwenden Sie für Caches, die größer als 1 MB sind, getExternalCacheDir(). Verwenden Sie für Caches mit einer Größe von maximal 1 MB getCacheDir(). Bei beiden Methoden wird das File-Objekt bereitgestellt, das die im Cache gespeicherten Daten Ihrer App enthält.

Das folgende Code-Snippet zeigt, wie Sie eine Datei im Cache speichern, die Ihre App vor Kurzem heruntergeladen hat:

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

Hinweis : Wenn Sie getExternalCacheDir() verwenden, um den Cache Ihrer App im freigegebenen Speicher zu platzieren, kann der Nutzer die Medien mit diesem Speicher entfernen, während Ihre App ausgeführt wird. Fügen Sie Logik hinzu, um den Cache-Fehler, der durch dieses Nutzerverhalten verursacht wird, ordnungsgemäß zu verarbeiten.

Achtung : Für diese Dateien wird keine Sicherheit erzwungen. Daher kann jede App, die auf Android 10 (API‑Level 29) oder niedriger ausgerichtet ist und die Berechtigung WRITE_EXTERNAL_STORAGE hat, auf die Inhalte dieses Cache zugreifen.

Weitere Informationen : Übersicht über Daten- und Dateispeicher

SharedPreferences im privaten Modus verwenden

Wenn Sie getSharedPreferences() verwenden, um die SharedPreferences-Objekte Ihrer App zu erstellen oder darauf zuzugreifen, verwenden Sie MODE_PRIVATE. So kann nur Ihre App auf die Informationen in der Datei mit den freigegebenen Einstellungen zugreifen.

Wenn Sie Daten zwischen Apps freigeben möchten, verwenden Sie keine SharedPreferences-Objekte. Folgen Sie stattdessen der Anleitung zum sicheren Teilen von Daten zwischen Apps.

Weitere Informationen

Dienste und Abhängigkeiten auf dem neuesten Stand halten

Die meisten Apps verwenden externe Bibliotheken und Geräteinformationen, um spezielle Aufgaben auszuführen. Wenn Sie die Abhängigkeiten Ihrer App auf dem neuesten Stand halten, machen Sie diese Kommunikationspunkte sicherer.

Sicherheitsanbieter der Google Play-Dienste prüfen

Hinweis : Dieser Abschnitt gilt nur für Apps, die auf Geräte mit installierten Google Play-Diensten ausgerichtet sind.

Wenn Ihre App die Google Play-Dienste verwendet, muss sie auf dem Gerät, auf dem sie installiert ist, aktualisiert werden. Führen Sie die Prüfung asynchron außerhalb des UI-Threads durch. Wenn das Gerät nicht auf dem neuesten Stand ist, lösen Sie einen Autorisierungsfehler aus.

Wenn Sie prüfen möchten, ob die Google Play-Dienste auf dem Gerät, auf dem Ihre App installiert ist, auf dem neuesten Stand sind, folgen Sie der Anleitung unter Sicherheitsanbieter zum Schutz vor SSL-Exploits aktualisieren.

Weitere Informationen :

Alle App-Abhängigkeiten aktualisieren

Prüfen Sie vor der Bereitstellung Ihrer App, ob alle Bibliotheken, SDKs und anderen Abhängigkeiten auf dem neuesten Stand sind:

  • Verwenden Sie für Erstanbieterabhängigkeiten wie das Android SDK die Aktualisierungstools in Android Studio, z. B. den SDK-Manager.
  • Prüfen Sie bei Drittanbieterabhängigkeiten die Websites der Bibliotheken, die Ihre App verwendet, und installieren Sie alle verfügbaren Updates und Sicherheitspatches.

Zugehörige Informationen : Build-Abhängigkeiten hinzufügen

Weitere Informationen

Weitere Informationen dazu, wie Sie Ihre App sicherer machen können, finden Sie in den folgenden Ressourcen: