Beitragsbild zum Artikel: Sichere Kommunikation in Apps (SSL)

Sichere Kommunikation in Apps (SSL)

In unserem letzten Artikel Sicherheitsrisiken in Apps verstehen. haben wir über die allgemeine Sicherheitsrisiken in Apps berichtet um ein Verständnis für das Thema zu wecken.


Heute schreiben wir über ein gezieltes Thema – Sichere Kommunikation in Apps (SSL). Wie auch schon in unserem ersten Artikel Wieso ist App Sicherheit wichtig? erwähnt, bedeutet die einfache Benutzung von SSL nicht zwangsläufig das Apps und Services sicher implementiert sind.

Inhalt des Artikels

  • Sichere Kommunikation mit Transport Layer Security (TLS),
  • Sichere Kommunikation in iOS,
  • Sichere Kommunikation in Android,
  • Zertifikats-Pinning ? Wie erklären es Ihnen.
    • Zertifikats-Pinning in iOS
    • Zertifikats-Pinning in Android mit API Version <= 24
    • Zertifikats-Pinning in Android mit API Version > 24

Sichere Kommunikation mit Transport Layer Security (TLS)

Bei der Entwicklung einer mobilen Anwendung sollten wir uns darum bemühen, dass die Netzwerkschicht sicher und daher nicht anfällig für Abhören ist. Aus diesem Grund sollte darauf geachtet werden, dass die gesamte Kommunikation über einen verschlüsselten Kanal erfolgt. Dieses Prinzip sollte auf alle Kommunikation angewendet werden, ein- schließlich Bluetooth und NFC.

Bei der Verwendung von TLS gilt:

  • Der gesamte Traffic sollte verschlüsselt sein. Dazu gehört auch der Traffic von Dritthersteller-Bibliotheken.
  • TLS 1.2 sollte verwendet werden und alles, was schwächer ist, sollte deaktiviert werden.
  • Zertifikate sollten korrekt validiert und nicht zu Testzwecken geschwächt werden.
  • Selbstsignierte Zertifikate sollten nicht akzeptiert werden, es sei denn, es wird ein Zertifikats-Pinning eingesetzt.
  • Für besonders sensible Daten sollten diese zusätzlich verschlüsselt werden.
  • Daten, die über sichere Verbindungen gesendet werden, sollten nicht protokolliert werden, weder in Logs, noch Debug-Logs.

Sichere Kommunikation in iOS

App Transport Security wurde in iOS 9 eingeführt und zwingt Anwendungen, TLS 1.2 zu nutzen. Das sollte nicht deaktiviert werden. In Fällen, in denen dies unvermeidbar ist, bitte nur auf einer Whitelist-Basis deaktivieren. Wildcards sollten nicht verwendet wer- den und nichts schwächeres als TLS 1.2 sollte akzeptiert werden.

Sichere Kommunikation in Android

Die neuere Version von Android (API > 24) unterstützt die Netzwerksicherheitskonfiguration, die es uns ermöglicht, den Plaintext-Traffic einfach auszuschalten. Dies kann durch Angabe des Attributes cleartextTrafficPermitted=“false“ in der Konfigurationsdatei des Projekts mit Namen network_security_config.xml definiert werden. Verwenden Sie dies mit Vorsicht, weil es trotzdem noch Szenarien gibt in denen unverschlüsselter HTTP-Traffic ermöglicht wird. (Stichwort java.net.Socket API)


Zertifikats-Pinning ? Wir erklären es Ihnen.

SSL/TLS arbeitet mit einer Vertrauenskette, in der ein Zertifikat verwendet wird, um die Verbindung zum Endpunkt zu validieren. Damit das Zertifikat vertrauenswürdig ist, wird eine Liste der vertrauenswürdigen Zertifizierungsstellen (CA) lokal auf dem Gerät gespeichert. Eine der Schwächen dieses Ansatzes ist, dass, sollte eine vertrauenswürdige CA kompromittiert werden, jedes Zertifikat, das mit ihrem privaten Schlüssel unterzeichnet wird, gültig und vertrauenswürdig sein wird. Alternativ wird jedem Zertifikat, das von dieser CA unterzeichnet wurde, vertrauenswürdig und gültig, wenn ein Angreifer in der Lage sein sollte, eine Fake-CA in die vertrauenswürdige CA-Liste zu installieren. Die Stärke dieses Ansatzes ist, dass jeder Endpunkt, der SSL/TLS verwendet, vertrauenswürdig ist, vorausgesetzt, Sie können der CA vertrauen, die das verwendete Zertifikat unterzeichnet hat.

Während ein Web-Browser verwendet wird, um sich mit vielen Websites zu verbinden, haben mobile Anwendungen den Vorteil, dass sie vorher wissen, mit welchen Domains sie sich verbinden. Das bedeutet, dass es möglich ist, die Sicherheit zu erhöhen, indem man nicht mehreren CAs, sondern nur einem spezifischen CA vertraut. Mit diesem Ansatz wird ein von einer kompromittierten oder Fake-CA signiertes Zertifikat nicht mehr gültig sein und dem System vertraut.

Implementieren können Sie das indem Sie den öffentlichen Schlüssel des vertrauenswürdigen Zertifikats in der Anwendung prüfen.

Je nach Anwendung sollte entschieden werden, gegen welches Zertifikat man sich nicht festlegen soll. Da dem Kunden eine Zertifikatskette präsentiert wird, wird es ein sichererer Ansatz sein, das Serverzertifikat zu pinnen. Das bedeutet, dass keine CA grundsätzlich vertrauenswürdig ist und sogar ein selbst signiertes Zertifikat verwendet werden darf, weil nur noch auf ein bestimmtes Zertifikat geprüft wird.

Entscheidet man sich für diesen Weg muss auch darüber nachgedacht werden wo in der Anwendung das selbstsignierte Zertifikat bzw. der zugehörige öffentliche Schlüssel gespeichert wird, da ein Angreifer versuchen wird dies gegen sein eigenes Zertifikat auszutauschen um die Verbindung abzuhören. Es empfehlt sich diese sensiblen Daten in das Binärprogramm einzubetten und ebenfalls zu verschlüsseln!

Wenn Sie anschließend ein fehlerhaftes Zertifikat im Anwendungs-Code entdecken, so können Sie die Anwendung mit einer entsprechenden Meldung beenden, da es sich hier um einen Angriff handelt. Sämtliche Kommunikation sollte zu diesem Zeitpunkt eingestellt sein.


Zertifikats-Pinning in iOS

Es gibt mehrere Bibliotheken, die es Entwicklern ermöglichen, Zertifikats-Pinning zu implementieren. Einige Empfehlungen beinhalten TrustKit und AFNetworking.

NSURLConnection
iOS bietet keinen nativen Ansatz, um Zertifikats-Pinning in einer NSURLConnection durchzuführen. Stattdessen kann ein NSURLConnectionDelegate verwendet werden, um die Umsetzung zu implementieren.
Delegate connection:canAuthenticateAgainstProtectionSpace und connection:didReceiveAuthenticationChallenge ist zu implementieren. Bei letzterem kann die Methode SecTrustEvaluate verwenden werden um das Zertifikat zu validieren.
Beispiel:
https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning

NSURLSession
Beginnend mit iOS 7 hat Apple NSURLSession vorgestellt. Eine Beispielhafte Implementierung finden Sie hier:
https://infinum.co/the-capsized-eight/how-to-make-your-ios-apps-more-secure-with-ssl-pinning

UIWebView
UIWebView bietet keine API, um Zertifikats-Pinning zu implementieren, aber sämtliche ausgehende Verbindungen können mit dem NSURLProtocol abgefangen werden. Es ist ein wenig kompliziert, aber nutzen Sie es um die Verbindung in einem UIWebView zu schützen.
Beispiel: https://developer.apple.com/library/content/sample-code/CustomHTTPProtocol/InTroduction/Intro.html.

WKWebView
Die modernere WKWebView unterstützt das Zertifikats-Pinning. Das ist also die empfohlene WebView Komponente. (unterstützt in iOS 8 und höher).


Zertifikats-Pinning in Android mit API Version <= 24

HttpUrlConnection
In der älteren Version von Android (vor Android N/API 24) kann Zertifikat-Pinning mit der Implementierung eines eigenen TrustManager erreicht werden. Dieser enthält dann alle ausgewählten vertrauenswürdigen Zertifikate. Ein Beispiel der Umsetzung findet sich hier: https://github.com/riramar/pubkey-pin-android.

WebView
Das WebView unterstützt keine Möglichkeit zum Pinning eines Zertifikats. Allerdings gibt es einen Workaround der für HTTP GET Requests verwendet werden kann. POST Requests unterstützt dieser Workaround leider nicht.
Ein alternativer Ansatz wäre es, Anfragen mit HTTPClient oder HttpURLConnection mit Zertifikat-Pinning zu machen und das geladene HTML in ein WebView zu laden. Dieser Ansatz würde nicht auf Seiten funktionieren, die Links oder Formulare enthalten, da nachträgliche Anfragen nicht berücksichtigt würden. Somit sind Frameworks die ein WebView verwenden und sensible Daten per Ajax oder Formularen verschicken mit Vorsicht zu genießen, da die Daten grundsätzlich von einem Angreifer abgefangen werden können.

CWAC-NetSecurity
CWAC-NetSecurity ist ein Backport von Android N und ermöglicht die Verwendung der gleichen Konfigurationsdateien in Android 4.2 und höher und somit Zertifikat-Pinning wie unter: https://developer.android.com/training/articles/security-config.html#CertificatePinning.
Es sollte darauf hingewiesen werden, dass es einige Einschränkungen gibt, wie zum Beispiel cleartextTrafficPermitted, der bei der Verwendung von HttpURLConnection ignoriert wird.

OkHttp
Die OkHttp Bibliothek unterstützt Zertifikats-Pinning mit der CertificatePinner Klasse. Um gegen einen öffentlichen Schlüssel des Zertifikats zu pinnen, finden Sie hier ein Code-Beispiel:
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CertificatePinning.java


Zertifikats-Pinning in Android mit API Version > 24

Android N führte die Netzwerk-Sicherheits-Konfiguration-API ein, die es uns ermöglicht, den öffentlichen Schlüssel des Zertifikats (SubjectPublicKeyInfo) in die von der AndroidManfest.xml-Datei referenzierte Datei network_security_config.xml zu legen. Dies ermöglicht auch Zertifikats-Pinning für WebViews. Ein Beispiel finden Sie hier: https://developer.android.com/training/articles/security-config#CertificatePinning.

What’s next?

Der Artikel war hilfreich? Wir erstellen kostenlose Sicherheitstests für Ihre App!

Alternativ bieten wir Ihnen ein E-Book mit 30+ Seiten rund um Sicherheit in Android und iOS Entwicklung. Jetzt anfordern.

Kommentare

  1. Schöner Artikel. Hier ein paar Anmerkungen:
    1.
    | API Version 24
    Was ist mit API Version 24, oder gibt es die nicht?

    2. Unnötige Worttrennung auf Smartphone z. B. unter- zeichnet

    3. Es bleibt eine Frage übrig. Was ist der praktikable und sichere Ansatz Zertifikate zu aktualisieren, wenn mal ein Zertifikat abläuft, für ungültig erklärt wird oder umbenannt werden muss?

    1. Hallo Rudolf,
      vielen Dank für deine Hinweise. Wir haben den Artikel entsprechend überarbeitet. Der Absatz < 24 ist eigentlich ein <= 24. Es schließt also die API Version 24 mit ein. Der Ansatz ein Zertifikat zu aktualisieren ist es den Public Key mit einem App-Update zu aktualisieren. Die Zertifikate sind im einfachsten Fall 3 Monate gültig. Es gibt aber auch Möglichkeiten ein Zertifikat 1, 2 oder 3 Jahre gültig zu halten, indem man ein SSL Zertifikat bei einer anderen Zertifizierungsstelle als Lets Encrypt erwirbt, wie bspw. unser Zertifikat von Liasoft, dass bis 2020 gültig ist.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.