Android WebView
that accepts all certificates¶
ID: java/improper-webview-certificate-validation
Kind: problem
Security severity: 7.5
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-295
Query suites:
- java-code-scanning.qls
- java-security-extended.qls
- java-security-and-quality.qls
Click to see the query in the CodeQL repository
If the onReceivedSslError
method of an Android WebViewClient
always calls proceed
on the given SslErrorHandler
, it trusts any certificate. This allows an attacker to perform a machine-in-the-middle attack against the application, therefore breaking any security Transport Layer Security (TLS) gives.
An attack might look like this:
The vulnerable application connects to
https://example.com
.The attacker intercepts this connection and presents a valid, self-signed certificate for
https://example.com
.The vulnerable application calls the
onReceivedSslError
method to check whether it should trust the certificate.The
onReceivedSslError
method of yourWebViewClient
callsSslErrorHandler.proceed
.The vulnerable application accepts the certificate and proceeds with the connection since your
WevViewClient
trusted it by proceeding.The attacker can now read the data your application sends to
https://example.com
and/or alter its replies while the application thinks the connection is secure.
Recommendation¶
Do not use a call SslerrorHandler.proceed
unconditionally. If you have to use a self-signed certificate, only accept that certificate, not all certificates.
Example¶
In the first (bad) example, the WebViewClient
trusts all certificates by always calling SslErrorHandler.proceed
. In the second (good) example, only certificates signed by a certain public key are accepted.
class Bad extends WebViewClient {
// BAD: All certificates are trusted.
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) { // $hasResult
handler.proceed();
}
}
class Good extends WebViewClient {
PublicKey myPubKey = ...;
// GOOD: Only certificates signed by a certain public key are trusted.
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) { // $hasResult
try {
X509Certificate cert = error.getCertificate().getX509Certificate();
cert.verify(this.myPubKey);
handler.proceed();
}
catch (CertificateException|NoSuchAlgorithmException|InvalidKeyException|NoSuchProviderException|SignatureException e) {
handler.cancel();
}
}
}
References¶
Common Weakness Enumeration: CWE-295.