Insecure SSL
ID |
kotlin.insecure_ssl |
Severity |
critical |
Resource |
Misconfiguration |
Language |
Kotlin |
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.net.URL
import java.security.cert.X509Certificate
fun main() {
// Set up an insecure TrustManager
val trustAllCerts = arrayOf<TrustManager>(
object : X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate>? = null
override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) {}
override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) {}
}
)
// Install the all-trusting trust manager
val sc = SSLContext.getInstance("SSL")
sc.init(null, trustAllCerts, java.security.SecureRandom())
HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory)
// Bypass hostname verification
val allHostsValid = HostnameVerifier { _: String?, _: SSLSession? -> true }
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid)
// Connect to a sample endpoint
val connection = URL("https://example.com").openConnection() as HttpsURLConnection
// 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.