freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

开源组件安全:netty 组件风险分析及修复详解
2024-10-23 14:44:31
所属地 河北省

最近遇到 CVE-2019-16869影响的 io.netty:netty组件的风险修复问题,但是 io.netty:netty全版本都有风险,无法通过升级的方式 解决组件的漏洞风险。

目前可以查到的信息也很有限,只有github上相关的补丁信息,

但是自己又对CVE-2019-16869的漏洞原理很感兴趣,网上资料了了,只说 Netty 错误地处理了 HTTP 标头,但是具体怎么错误处理的,以及修复的原理是什么,没有找到完整分析过的文章,

特此完整整理分析如下:

依赖坐标:

io.netty:netty

...

漏洞风险——Netty 存在 HTTP 请求走私漏洞

CVE-2019-16869

漏洞描述

Netty 是一个非阻塞I/O客户端-服务器框架,主要用于开发Java网络应用程序,如协议服务器和客户端。

Netty 的受影响版本容易受到 HTTP 请求走私的攻击,原因是 Netty 错误地处理了 HTTP 标头中冒号前的空格如 Transfer-Encoding : chunked 。攻击者可利用此漏洞进行 HTTP 请求走私攻击,绕过安全控制,未经授权访问敏感数据。

参考信息

https://nvd.nist.gov/vuln/detail/CVE-2019-16869

https://github.com/netty/netty/issues/9571

https://github.com/netty/netty/pull/9585

https://github.com/netty/netty/commit/017a9658c97ff1a1355c31a6a1f8bd1ea6f21c8d

漏洞原理 及 修复

CVE-2019-16869 ,这枚 CVE 是 OPPO 子午互联网安全实验室发掘的,是关于 Netty 中间件存在 HTTP Smuggling 漏洞。

HTTP请求走私漏洞的核心原因是由于前端服务器后端服务器在处理HTTP请求头时存在差异,导致请求被错误解析。‌ 例如,Content-LengthTransfer-Encoding头的处理不一致,可能导致请求被分割或合并,从而引发安全漏洞‌。

HTTP请求走私漏洞的类型包括:

HTTP请求走私漏洞的危害包括:

  • 会话劫持‌:攻击者可以利用该漏洞劫持用户会话,获取敏感信息如登录凭证和会话标识符。
  • 身份伪装‌:攻击者可以伪装成合法用户,绕过安全机制,获得未授权访问权限。
  • 敏感信息泄露‌:攻击者可能泄露用户的个人身份信息、金融数据等。
  • 业务破坏‌:对业务逻辑和系统配置造成破坏‌。

在 Netty 4.1.42.Final 版本之前对于 Header 头的处理是使用 splitHeader方法,其中关键代码如下:

for (nameEnd = nameStart; nameEnd < length; nameEnd ++) {
  char ch = sb.charAt(nameEnd);
  if (ch == ':' || Character.isWhitespace(ch)) {
    break;
  }
}

其他的代码我们并不需要过多了解,这里我们可以知道这里将空格与:冒号同样处理了,也就是如果存在空格会把:其之前的 field name 正常处理,并不会抛出错误或者进行其他操作。这样就与 RFC 标准的规范不一致了,于是就会产生解析差异。

@Bi3g0 构建了比较清晰的漏洞原理图:

1729665949_67189b9d01fe8c4c0ee1b.png!small?1729665949754

这里的例子是采用 ELB 作为 Front 服务器,Netty 作为 Backend 服务器进行举例,我们发送如下请求:

POST /getusers HTTP/1.1
Host:www.backend.com
Content-Length:64
Transfer-Encoding :chunked
0 GET /hacker HTTP/1.1 Host: www.hacker.com hacker: hacker

elb是如何处理Incorrect TE

1)攻击请求

POST /getusers HTTP/1.1
主机:www.backend.com
内容长度:64
传输编码:分块

0

GET /hacker HTTP/1.1
主机: www.hacker.com
hacker: hacker

2)ELB处理请求的方式:

1729666058_67189c0ab131881aa48c5.png!small?1729666059201

ELB 会将 Transfer-Encoding 字段忽略,因为它与冒号中间有一个空格,不符合 RFC 标准(参考 https://tools.ietf.org/html/rfc7230#section-3.2.4),

ELB 会使用 Content-Length 作为解析标准,于是会认为以上请求是一个完整的请求,继而扔给 Backend 服务器,也就是 Netty ,Netty 在这里会优先解析 Transfer-Encoding ,即使这个字段不符合 RFC 标准,但是因为它的实现方式不严格, 所以这里因为优先解析 Transfer-Encoding 的原因,它会将这个请求拆分为两个请求:

POST /getusers HTTP/1.1
Host:www.backend.com
Content-Length:64
Transfer-Encoding :chunked

0

GET /hacker HTTP/1.1
Host:www.hacker.com
hacker:hacker

这样就造成了 HTTP Smuggling 攻击。

Netty 于 4.1.42 Final 版本修复了这个漏洞:Correctly handle whitespaces in HTTP header names as defined by RFC72…

Netty 可以识别TE[space]: field value为错误的标头或自定义标头。

1)Netty 可以识别TE[space]: field value 自定义 header,Netty 应该像 elb 一样根据 header 来分离请求CL并转发整个 header TE[space]: field value。

2)或者Netty可以识别TE[space]: field value为不正确的header,返回响应码400(Bad Request)。

当我们发送 field name 与 : 之间有空格的 header 请求时, netty 会“正确”地返回 400 ,如下说明:

1729666450_67189d92c79a6212925d8.png!small?1729666452046

代码补丁如下:

https://github.com/netty/netty/commit/017a9658c97ff1a1355c31a6a1f8bd1ea6f21c8d

for(nameEnd =nameStart;nameEnd <length;nameEnd ++){
    charch =sb.charAt(nameEnd);
    if(ch ==':' ||(!isDecodingRequest() && Character.isWhitespace(ch))){ 
        break; 
    }
}


以上为总结分析,如有其他建议可留言沟通

# web安全 # 开源组件安全 # 开源组件检测 # 开源组件分析 # SCA工具
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录