Authentication / Missing Certificate Pinning
Description
Missing Certificate Pinning is an authentication vulnerability (CWE-295) that occurs when an application fails to verify a given certificate against its trusted peers, allowing a malicious certificate to be used as authentication. This type of vulnerability is often found in infrastructure applications, such as web browsers and mobile applications, as well as in other applications that rely on SSL for authentication. According to the OWASP Testing Guide, it can be caused by incorrectly configured or missing certificate pinning, allowing for the use of expired, self-signed, or malicious certificates.
Risk
Missing Certificate Pinning can lead to serious security issues, as it leaves the system vulnerable to Man-in-the-Middle (MitM) attacks. Without the proper authentication of certificates, the system will be unable to detect and prevent malicious actors from intercepting and manipulating the encrypted traffic, leading to the potential exposure of sensitive data. As such, it is important that certificate pinning is properly configured and monitored.
Solution
In order to prevent this vulnerability, it is important to ensure that all certificates are properly verified against a known trusted source. This can be done through the use of Certificate Pinning, which is the binding of a certificate to its intended purpose, such as a web server or application. It is also important to ensure that all certificates are updated regularly and that any new certificates are properly validated.
Example
The following code is an example of how to properly implement certificate pinning in an Android application, taken from the CVE-2020-13779 listing.
// Set up the trusted certificates
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore trustedKeyStore = KeyStore.getInstance("BKS");
InputStream keyStoreStream = context.getResources().openRawResource(R.raw.cert_store);
try {
// Set the trust store
trustManagerFactory.init(trustedKeyStore);
// Add the certificates to the trust store
trustedKeyStore.load(keyStoreStream, "password".toCharArray());
// Set the trust managers
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
// Add the certificates to the SSLContext
SSLContext.getInstance("TLS").init(null, trustManagers, new SecureRandom());
} finally {
keyStoreStream.close();
}