Insecure TLS Certificate Validation
不安全的 TLS 证书验证
描述
不安全的 TLS 证书验证是在建立客户端和服务器之间安全连接时存在的一种漏洞。TLS(传输层安全)是一种提供互联网上安全通信的加密协议。当客户端通过 TLS 连接到服务器时,它会检查服务器的数字证书以验证其身份并确保连接是安全的。
当客户端未能正确验证服务器的证书时,就会发生不安全的 TLS 证书验证,这允许攻击者冒充服务器并拦截或修改客户端和服务器之间的通信。这可能导致敏感信息被窃取、修改或暴露。
以下是 TLS 证书验证中一些常见的弱点:
-
过期的证书: 已过期的证书不再被视为有效。然而,不检查证书过期日期的客户端可能会接受过期的证书,而该证书可能已被吊销或遭到泄露。
-
自签名证书: 自签名证书是由颁发该证书的同一实体签名的证书。由于没有独立的第三方来验证证书的真实性,信任自签名证书的客户端可能容易受到中间人攻击(man-in-the-middle attack)。
-
主机名不匹配的证书: 证书是为特定的域名或 IP 地址颁发的。如果客户端连接到的服务器,其证书与主机名或 IP 地址不匹配,客户端可能容易受到中间人攻击。
-
不受信任的根证书: 根证书是证书链中的顶级证书,用于验证链中所有证书的真实性。如果客户端不信任服务器使用的根证书,它可能会接受由另一个不受信任的根证书签名的欺诈证书。
-
被吊销的证书: 如果证书遭到泄露或不再被认为是可信的,它可以被吊销。不检查证书吊销状态的客户端可能会接受被吊销的证书,这可能被用于执行中间人攻击。
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.security.SecureRandom;
public class HttpsRequestWithoutTlsVerification {
public static void main(String[] args) throws Exception {
// Disable SSL/TLS verification
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) {}
}};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new SecureRandom());
// Create connection and set SSL context
URL url = new URL("https://example.com");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(sslContext.getSocketFactory());
// Send HTTP request
conn.setRequestMethod("GET");
int responseCode = conn.getResponseCode();
System.out.println("Response code: " + responseCode);
}
}
import 'dart:io';
void main() async {
var client = HttpClient();
// Disable SSL certificate validation
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
// Make HTTP request
var request = await client.getUrl(Uri.parse('https://example.com'));
var response = await request.close();
print('Response code: ${response.statusCode}');
client.close();
}
建议
为了降低不安全 TLS 证书验证的风险,建议应用程序在客户端和服务器上都实施安全的证书验证机制。这包括:
- 检查服务器证书的有效性,以确保它未过期、未被吊销,并且是由受信任的证书颁发机构颁发的。
- 配置主机名验证,以确保证书与服务器的域名相匹配,从而防止接受具有无效主机名的证书。
- 使用受信任的证书颁发机构,并避免使用自签名证书或不受信任的根证书。
此外,重要的是使用最新的安全补丁使应用程序以及所使用的任何库或框架保持最新状态,并定期测试应用程序的安全态势,以识别可能存在的任何漏洞。
链接
标准
- PCI_STANDARDS:
- REQ_2_2
- REQ_4_2
- REQ_6_2
- REQ_6_3
- REQ_6_4
- REQ_11_3
- SOC2_CONTROLS:
- CC_2_1
- CC_4_1
- CC_6_7
- CC_7_1
- CC_7_2
- CC_7_4
- CC_7_5