apachestruts2文件上传漏洞
2013年7月,文件Struts2爆出那个著名的上传S2-016漏洞时,我正好在给一家电商做安全巡检。漏洞那天下午三点多,文件同事扔过来一个URL,上传说“你试试这个”。漏洞打开一看,文件服务器上已经被人传了个jsp木马,上传文件名还起得挺嚣张——cmd.jsp。漏洞这就是文件Struts2文件上传漏洞的典型场景:攻击者通过构造恶意请求,把任意文件传到服务器上,上传然后拿到webshell。漏洞
问题出在Struts2的文件FileUploadInterceptor拦截器上。它原本负责处理文件上传,上传但早期版本对上传文件的漏洞类型、路径、内容检查都太松。具体点说,当请求经过ParametersInterceptor时,如果参数名里带了top.fileFileName这类OGNL表达式,攻击者就能绕过白名单,直接控制上传文件的存储位置和文件名。更狠的是,有些版本连Content-Type都不校验,你传个.jsp文件上去,它照样给你存到web目录下。
我见过最离谱的一个案例。某政府网站用了Struts2 2.3.15,运维觉得“我们只是内部系统,没事”。结果攻击者用Content-Type: image/jpeg伪装,实际上传了个shell.jsp,文件内容开头加了GIF89a绕过图片头检测。上传成功后,通过/upload/shell.jsp?cmd=whoami直接执行系统命令。从扫描到拿权限,前后不到两分钟。
为什么这个漏洞影响这么大?因为Struts2在Java Web开发里太常见了。很多老系统、内部OA、甚至银行后台,都跑着Struts2。而且文件上传功能几乎是标配——用户头像、附件、导入Excel,哪个不需要?攻击面天然就大。更麻烦的是,很多开发人员压根不知道struts.xml里allowedTypes和allowedExtensions的配置区别,以为设了allowedTypes=image/png就安全了,结果攻击者改个Content-Type就绕过去了。
修复方案其实不复杂。升级到Struts 2.5.22以上,或者至少打上对应补丁。如果暂时升不了,就在struts.xml里把allowedExtensions写死,比如allowedExtensions=jpg,png,gif,同时用allowedTypes做二次校验。但最关键的,还是别把上传目录放在web可访问路径下。我见过太多人图省事,直接upload文件夹扔在webapp根目录,这不等于把刀递给别人吗?
还有个细节容易被忽略:Struts2的fileUpload拦截器默认会解析Content-Disposition里的filename字段。如果文件名里带了../,老版本会直接拼接路径,导致目录穿越。攻击者可以传到WEB-INF/classes下,覆盖配置文件。这种利用方式比传jsp更隐蔽,但危害一点不小。
说到底,这个漏洞的本质是框架对用户输入过度信任。Struts2当年为了灵活,把OGNL表达式玩得太花,结果参数名、文件名、甚至Content-Type都能被注入。安全圈有句话:“Struts2的漏洞史,就是半部Java Web安全史。” 虽然有点夸张,但确实反映了它在设计上的历史包袱。现在新项目用Spring Boot居多,但维护老系统的兄弟,还是得盯紧点。别等到服务器上多了个cmd.jsp,才想起来升级。
(责任编辑:综合)












