Struts2漏洞

热点 2026-10-17 05:28:09 99836

2013年7月,漏洞Struts2的漏洞S2-016漏洞被公开时,国内大量政府网站和银行系统在几个小时内就被批量拿下了。漏洞攻击者只需要在URL里构造一个以"action:"或"redirect:"开头的漏洞OGNL表达式,就能直接执行任意命令。漏洞那几天圈子里流传的漏洞webshell截图满天飞,有人开玩笑说"比扫目录还快"。漏洞

这不是漏洞Struts2第一次出事,也远不是漏洞最后一次。从2010年的漏洞S2-005到2017年的S2-045,再到2020年又冒出来的漏洞S2-059,这个框架几乎每年都要贡献一两个高危漏洞。漏洞一个Java Web框架能持续十年给安全圈"供货",漏洞本身就说明问题不在某个具体漏洞,漏洞而在它的漏洞设计思路。

Struts2的核心是OGNL(Object-Graph Navigation Language)。这东西本来是用来在视图层方便地读写对象属性的,比如 user.address.city 这样一路点下去就能拿到值。问题在于,Struts2把OGNL的解析权交给了用户输入。当框架用 %{ ...} 或 ${ ...} 去解析参数时,如果参数里嵌了恶意表达式,OGNL引擎会老老实实执行它。更麻烦的是OGNL能访问Java的Runtime类,等于把执行系统命令的钥匙递了出去。

拿S2-045举例。漏洞出在Jakarta Multipart解析器处理Content-Type头的时候。攻击者发一个畸形的Content-Type,Struts2在报错信息里拼接了这个头的内容,然后用OGNL解析——命令就这么执行了。整个利用过程不需要任何认证,一个curl请求就能拿到服务器权限。我当时在测试环境复现过,命令回显直接出现在HTTP响应体里,干净利落,连盲打都不用。

为什么这类漏洞反复出现?我的观察是,Struts2的历史包袱太重。它从WebWork继承了大量基于拦截器和值栈的设计,参数在到达业务代码之前要经过层层处理。每一层都可能触发OGNL解析,而开发者根本感知不到。你写一个普通的Action,配一个普通的struts.xml,以为只是在处理表单提交,实际上框架已经在背后做了很多"聪明"的事情。这种隐式行为在安全上就是灾难。

另一个被忽视的点是默认配置。Struts2的 struts.enable.DynamicMethodInvocation 和 struts.devMode 在不少生产环境里居然是开着的。devMode会暴露详细的错误堆栈,DMI则允许通过URL动态调用Action的任意方法。这两样加在一起,攻击面直接翻倍。很多运维和开发人员根本不知道这些开关的存在,直到被扫了才发现。

修复建议其实不复杂。升级到最新版本是第一步,官方在每次漏洞爆发后都会发补丁。但光升级不够,还得做几件事:关掉DMI,关掉devMode,在web.xml里加安全过滤器拦截异常参数,用WAF做一层OGNL关键字的规则。如果项目里Struts2只是用来做MVC跳转,没有用到它的高级特性,认真考虑换Spring MVC或者直接上Spring Boot。迁移成本没有想象中那么高,但安全收益是实打实的。

我见过太多团队在漏洞爆发时连夜打补丁,过几个月又因为新漏洞再来一遍。这种循环消耗的精力,早就超过了当初换框架的成本。Struts2不是不能用,但你得清楚自己在用什么,以及它随时可能给你带来什么。

本文地址:http://www.79wt.cn/news/1281e1899853.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

友情链接