java - 在 HostnameVerifier 中信任 peerHost 是否安全?
问题描述
在其中一条规则中, SonarQube 不允许HostnameVerifier
盲目接受每个主机的假人:
Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String requestedHost, SSLSession remoteServerSession) {
return true; // Noncompliant
}
}).build();
并且此示例作为兼容代码提供:
Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String requestedHost, SSLSession remoteServerSession) {
return requestedHost.equalsIgnoreCase(remoteServerSession.getPeerHost()); // Compliant
}
}).build();
但是在SSLSession.getPeerHost()的 javadoc 中,我可以读到:
此值未经身份验证,不应依赖。它主要用作 SSLSession 缓存策略的提示。
这让我很困惑。如果该getPeerHost()
值不可信,那么它如何成为修复漏洞的推荐合规代码?它安全吗?它阻止了哪些攻击,哪些攻击没有阻止?
解决方案
虽然使用“peerHost”而不是笼统的“返回真实”肯定要好得多,但它仍然不是没有风险。'peerHost'可以通过反向 DNS 检索。这导致了CWE-350 的缺陷:依赖反向 DNS 解析进行安全关键操作,MITRE 对此表示如下:
由于 DNS 名称很容易被欺骗或误报,并且软件可能难以检测受信任的 DNS 服务器是否已被入侵,因此 DNS 名称不构成有效的身份验证机制。
当软件对 IP 地址执行反向 DNS 解析时,如果攻击者控制该 IP 地址的服务器,则攻击者可以使服务器返回任意主机名。因此,攻击者可能能够绕过身份验证,导致在日志文件中记录错误的主机名以隐藏活动,或执行其他攻击。
攻击者可以通过 (1) 破坏 DNS 服务器并修改其记录(有时称为 DNS 缓存中毒)或 (2) 合法控制与其 IP 地址关联的 DNS 服务器来欺骗 DNS 名称。
最好的做法是解决为什么给定的主机名与证书中的主机名不匹配的根本问题。请注意,SonarSource 已更新其示例代码以反映这一点:https ://rules.sonarsource.com/java/RSPEC-5527
推荐阅读
- python - 如何在 html 页面中添加烧瓶自动索引
- winapi - 为什么 GetCaretPos 返回与 GetTextExtentPoint32 不同的远程编辑
- python - 检查端子颜色
- javafx - javafx:在 Platform.runLater 中使用 StageStyle.TRANSPARENT 进行弹出和断点设置时的奇怪效果
- javascript - 如何使用语言国家代码相应地自定义货币符号?
- sql - 使用 sqlPackage.exe 部署 dacpac 时仅包括 SP、视图、表和函数
- r - 在 Plotly 和 R 中以红色显示底片
- svn - 将现有存储库添加到 svn
- xamarin.forms - 多平台库项目中的依赖服务?
- matlab - 在 Simulink 中绘制植物传递函数的问题