Understand security risks in apps in our last article. We reported on the general security risks in apps to gain an understanding of the topic.
Today we write about Safe communication in apps (SSL). As in our first article Why, is app security important? mentions, the ease of use of SSL does not necessarily mean that apps and services are securely implemented.
Content of the article
- Secure communication with Transport Layer Security (TLS),
- Secure communication in iOS,
- Secure communication in Android,
- Certificate pinning? How do you explain it.
- Certificate pinning in iOS
- Certificate pinning in Android with API version < 24
- Certificate pinning in Android with API version > 24
Secure communication with Transport Layer Security (TLS)
When developing a mobile application, we should strive to ensure that the network layer is secure and therefore not susceptible to eavesdropping. For this reason, care should be taken to ensure that all communication is made via an encrypted channel. This principle should be applied to all communication, including Bluetooth and NFC.
When using TLS, the following applies:
- All traffic should be encrypted. This includes third-party libraries ‘ traffic.
- TLS 1.2 should be used and anything weaker should be disabled.
- Certificates should be validated correctly and not weakened for testing purposes.
- Self-signed certificates should not be accepted unless certificate pinning is used.
- For particularly sensitive data, this should also be encrypted.
- Data sent over secure connections should not be logged, either in logs or debug logs.
Secure communication in iOS
App Transport Security was introduced in iOS 9 and forces applications to use TLS 1.2. This should not be disabled. In cases where this is unavoidable, please only disable on a whitelist basis. Wildcards should not be used-and nothing weaker than TLS 1.2 should be accepted.
Secure communication in Android
The newer version of Android (API > 24) supports the network security configuration, which allows us to easily turn off the plastic traffic. This can be defined by specifying the attributes cleartextTrafficPermitted = “false” in the project’s configuration file called network _security_config.xml. Use this with caution because there are still scenarios where unencrypted HTTP traffic is possible. (Keyword java.net.Socket API)
Certificate pinning? How do you explain it.
SSL/TLS works with a chain of trust in which a certificate is used to validate the connection to the endpoint. In order for the certificate to be trustworthy, a list of trusted certification bodies (CA) is stored locally on the device. One of the weaknesses of this approach is that should a trusted CA be compromised, any certificate signed with their private key will be valid and trustworthy. Alternatively, any certificate signed by this CA becomes trustworthy and valid if an attacker should be able to install a fake CA in the trusted CA list. The strength of this approach is that any endpoint that uses SSL/TLS is trustworthy, provided you can trust the CA that signed the certificate used.
While a web browser is used to connect to many websites, mobile applications have the advantage of knowing beforehand which domains they connect to. This means that it is possible to increase security by trusting not multiple CAs, but only one specific CA. With this approach, a certificate signed by a compromised or fake CA will no longer be valid and will trust the system.
You can implement this by checking the public key of the trusted certificate in the application.
Depending on the application, it should be decided which certificate should not be committed against. Because the customer will be presented with a chain of certificates, it will be a safer approach to pin the server certificate. This means that no CA is fundamentally trustworthy and can even be used for a self-signed certificate, because only a specific certificate is still checked.
If one chooks for this path, one must also think about where in the application the self-signed certificate or The associated public key is saved because an attacker will try to exchange this for his own certificate to eavesdrop on the connection. It is recommended to embed this sensitive data in the binary program and also to encrypt it!
If you then discover a faulty certificate in the application code, you can end the application with a corresponding message because this is an attack. All communications should be discontinued at this time.
Certificate pinning in iOS
There are several libraries that allow developers to implement certificate pinning. Some recommendations include TrustKit and AFNetworking.
IOS does not offer a native approach to performing certificate pinning in a NSURLConnection. Instead, a NSURLConnectionDelegate can be used to implement the implementation.
Delegate connection: canAuthenticateAgainstProtectionSpace and connection: didReceiveAuthenticationChallenge is to be implemented. For the latter, the SecTrustEvaluate method can be used to validate the certificate.
Starting with iOS 7, Apple has unveiled NSURLSession. A sample implementation can be found here:
UIWebView does not provide an API to implement certificate pinning, but all outgoing connections can be intercepted with the NSURLProtocol. It’s a little complicated, but use it to protect the connection in a UIWebView.
The more modern WKWebView supports certificate pinning. So this is the recommended WebView component. (Supported in iOS 8 and above).
Certificate pinning in Android with API version < 24
In the older version of Android (before Android N/API 24), certificate pinning can be achieved with the implementation of your own TrustManager. This will then contain all selected trusted certificates. An example of implementation can be found here: https://github.com/riramar/pubkey-pin-android.
The WebView does not support the possibility of pinning a certificate. However, there is a workaround that can be used for HTTP GET requests. POST Requests unfortunately does not support this workaround.
An alternative approach would be to make requests with HTTPClient or HttpURLConnection with certificate pinning and load the loaded HTML into a WebView. This approach would not work on pages that contain links or forms because subsequent requests would not be considered. Thus, frameworks that use a WebView and send sensitive data via Ajax or forms must be treated with caution, as the data can basically be intercepted by an attacker.
CWAC-NetSecurity is a backport of Android N and allows the use of the same configuration files in Android 4.2 and above and thus certificate-inning as under: https://developer.android.com/training/articles/security-config.html#CertificatePinning.
It should be noted that there are some limitations, such as cleartextTrafficPermitted, which is ignored when using HttpURLConnection.
The OkHttp library supports certificate pinning with the CertificatePinner class. To pin against a public key of the certificate, here is a code example:
Certificate pinning in Android with API version > 24
Android N introduced the network security configuration API, which allows us to place the public key of the certificate (SubjectPublicKeyInfo) in the file network_security_config.xml referenced by the AndroidManfest.xml file. This also allows certificate pinning for WebViews. An example can be found here: https://developer.android.com/training/articles/security-config#CertificatePinning.
That write-up was helpful? We are doing free security checks for your app.
Want a free e-book about Android and iOS security? (30 Pages full of interesting write-ups!) Request it now.