Insecure SSL
ID |
java.insecure_ssl |
Severity |
critical |
Resource |
Misconfiguration |
Language |
Java |
Tags |
CWE:295, NIST.SP.800-53, OWASP:2021:A2, OWASP:2021:A7, PCI-DSS:6.5.4 |
Description
Insecure SSL refers to the usage of insecure configurations with SSL/TLS protocols that could compromise data confidentiality, integrity, or authenticity while in transit.
Developers might inadvertently create SSL/TLS connections without enforcing adequate security measures, risking man-in-the-middle (MITM) attacks.
Rationale
The danger of insecure SSL configurations generally stem from mistakes such as using outdated SSL/TLS protocols, disabling certificate validation, or failing to verify hostnames. Code snippets that disable these validations are useful for quick testing. However, leaving them in production can create serious security vulnerabilities.
SSL/TLS security is undermined by:
-
Trusting all certificates, effectively ignoring trust chain verification.
-
Allowing all hostnames to be valid, circumventing checks for URL domain validity and authenticity.
-
Disabling Certificate Revocation List (CRL) or Online Certificate Status Protocol (OCSP) checks for certificate revocation.
-
Using insecure protocols like SSLv3 and TLS 1.0 / 1.1.
Here’s a simple example that highlights typical insecure coding practices with SSL:
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
public class InsecureSSLExample {
public static void main(String[] args) throws Exception {
// Set up an insecure TrustManager
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Bypass hostname verification
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
// Connect to a sample endpoint
HttpsURLConnection connection =
(HttpsURLConnection) new URL("https://example.com").openConnection();
// Use the connection...
}
}
This weak configuration undermines security, making it easy for an attacker to intercept or alter communications without being detected.
Remediation
To remediate issues related to insecure SSL configurations:
-
Use a Trust Store: Always configure the software to use a well-maintained trust store with up-to-date certificates. Avoid using custom trust managers that disable certificate validation.
-
Enforce Hostname Verification: Ensure that hostname verification is enabled so that the TLS clients can match the server’s hostname against its certificate’s naming information.
-
Keep Protocols and Libraries Up-to-date: Regularly update the runtime environment and any third-party libraries to ensure compatibility with the latest secure protocols (e.g., TLS 1.2 or 1.3), avoiding outdated versions like SSLv3.
-
Review Libraries for Vulnerabilities: Regularly audit the libraries and dependencies used in your software projects for known vulnerabilities.
References
-
CWE-295 : Improper Certificate Validation.
-
MSC00-J. Use SSLSocket rather than Socket for secure data exchange, in CERT Secure Coding Standard for Java.