SV.ECV

此检查器会检测空 SSL 证书验证的情况。

将在无关紧要地实施 org.apache.http.conn.ssl.X509HostnameVerifier 接口的“验证”方法的类上报告 SV.ECV 缺陷。

漏洞与风险

如果证书验证为空,所有 SSL 证书都将视为有效证书。这样便存在中间人攻击的可能性,此类攻击发生时,入侵者能够访问安全数据。

缓解与预防

要预防此问题,实现 X509HostnameVerifier 接口的类的“验证”方法应执行实际的验证,并且其不应为空或由单个返回语句组成。我们建议适当地重写 HostnameVerifier.verify(),以检查特定于主机名的证书数据是否与服务器主机名相匹配。

漏洞代码示例

复制
private static X509HostnameVerifier ACCEPT_ALL_HOSTNAMES =  
    new X509HostnameVerifier() {
        public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
        }
        public void verify(String host, X509Certificate cert) throws SSLException {
        }
        public void verify(String host, SSLSocket ssl) throws IOException {
        }
        public boolean verify(String host, SSLSession session) { 
        return true;
    }
};

在此示例中,X509HostnameVerifier 设置为接受所有主机名。

漏洞代码示例 2

复制
import javax.net.ssl.*;
import java.security.cert.*;
 
class Host {
 
    private static void disableSSLVerification(HttpsURLConnection connection) {
        connection.setHostnameVerifier(new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
  }
}

Klocwork 在第 8 行报告了 SV.ECV 缺陷,指出“方法验证未执行任何操作”。

修正代码示例 2

复制
import javax.net.ssl.*;
import java.security.cert.*;

class Host {
 
    private static void retrieve() {
        HttpsURLConnection uc = (HttpsURLConnection) u.openConnection();
        uc.setHostnameVerifier(new HostnameVerifier() {
 
            public boolean verify(String hostname, SSLSession session) {
                boolean valid = false;
                try {
                    String expectedHostname = hostname.toLowerCase();
                    //...
                } catch (Exception ex) {
                }
            }
        });
    }
}

在将 HostnameVerifier.verify() 指定为 false 并提供正确的主机名后,问题得到解决。