Do not trust all certificates
Trusting all certificates allows anybody to do a man in the middle attack
Mobile app security is definitely an area where paranoia makes sense. A not so hypothetical scenario; we are trying to make a get API call and are getting the following error:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
We panic. Search for help and find the following solution:
// 1
class TrustAllTrustManager : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager")
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
@SuppressLint("TrustAllX509TrustManager")
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return emptyArray()
}
}
Should we implement this solution in our code?
Absolutely not!
Trusting all certificates allows anybody to do a man in the middle attack. So what should we do instead?
We should add a Network Security Configuration file.
- Add
res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">monkey.work</domain>
<trust-anchors>
<certificates src="@raw/trusted_roots"/>
</trust-anchors>
</domain-config>
</network-security-config>
- To the
application
section ofAndroidManifest.xml
add
<application
android:networkSecurityConfig="@xml/network_security_config"
- Add
res/raw/trusted_roots
- The file may contain multiple certificates
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
- To extract all certificates from a server
echo | openssl s_client -showcerts -servername monkey.work -connect monkey.work:443 2>&1 | \
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > monkey.work.pem
Subscribe to The infinite monkey theorem
Get the latest posts delivered right to your inbox