描述
Spring Security 在处理安全约束时未考虑 URL 路径参数。通过向请求添加带有编码“/”的 URL 路径参数,攻击者可能能够绕过安全约束。此问题的根本原因是 Servlet 规范中关于路径参数处理的缺乏明确性(见下文)。一些 Servlet 容器在 getPathInfo() 返回的值中包含路径参数,而另一些则不包含。Spring Security 使用 getPathInfo() 返回的值作为将请求映射到安全约束过程的一部分。路径参数的意外存在可能导致约束被绕过。
Apache Tomcat(所有当前版本)的用户不受此漏洞影响,因为 Tomcat 遵循 Servlet 专家组先前提供的指导,并从 getContextPath()、getServletPath() 和 getPathInfo() [1] 返回的值中剥离路径参数。
使用其他基于 Apache Tomcat 的 Servlet 容器的用户可能会受到影响,具体取决于路径参数的处理是否已修改。
IBM WebSphere Application Server 8.5.x 的用户已知受影响。
使用其他实现 Servlet 规范的容器的用户可能会受到影响。
[1] https://issues.apache.org/bugzilla/show_bug.cgi?id=25015
受影响的 Spring 产品和版本
Spring Security 3.2.0 - 3.2.9 Spring Security 4.0.x - 4.1.3 Spring Security 4.2.0 更旧的不受支持的版本也受到影响
缓解措施
采用以下任一缓解措施将防止此漏洞。
使用已知不在 getServletPath() 和 getPathInfo() 返回值中包含路径参数的 Servlet 容器 升级到 Spring Security 3.2.10、4.1.4 或 4.2.1 将在检测到编码“/”时拒绝请求并抛出 RequestRejectedException。注意:如果您希望禁用此功能,可以通过设置 DefaultHttpFirewall.allowUrlEncodedSlash = true 来禁用。但是,禁用此功能将意味着应用程序在(在 getServletPath() 或 getPathInfo() 中返回路径参数的容器中)容易受到攻击。
致谢
该问题由 NTT DATA Corporation 的 Shumpei Asahara 和 Yuji Ito 发现,并负责任地报告给 Pivotal。
参考资料