记录一次header manipulation的解决

如题,最近在进行系统安全测试的时候,文件下载出了点问题,fortify扫描出了header manipulation漏洞。因为接手的是别人的代码,很疑惑他当时为什么要用控制响应头的方法去进行文件下载传输。

原来的代码大概是这样的

@RequestMapping("files/download",method=RequestMethod.GET)
public void download(@RequestParam String fileName){
    FileInfo fileInfo = RedisUtil.get(RedisKeyConstants.FILE_PREKEY + fileName);
    //业务逻辑处理
    response.setHeader("Content-disposition","attachment;fileName=" + fileName);
    ....
}

在response.setHeader这一行一直报header manipulation

乍一看确实是没什么问题的,但怀着b了狗的心情,csdn上找了一番,都是让我去校验文件名。后来抄了个正则,校验了一下,然并卵,fortify并不知道你校验了。。。

万恶的测试,迟早有一天我要把你们全部砍死。。心里默默的yy了两句。

后来找了篇文章,看到了这个漏洞的共计原理,本质原因就是你使用了用户的入参给用户进行了响应。。那么问题来了,如果用户的入参里本身就包含了一段响应信息,甚至是响应了一段js代码,或者是响应了一个钓鱼网站会发生什么呢。。小站当然不用担心。。。但,我们这么看中安全测试。。所以你懂的。。。

找到了原因,自然就找到了解决办法。。原谅我bb了这么久。。下面给答案吧。。

public void download(@RequestParam String fileName){
    //查询fileInfo的信息
    FileInfo fileInfo = service.getFileInfo(fileName);
    //处理业务逻辑
    //设置响应头,这一行不要直接使用用户入参的fileName以避免http响应被攻击者分割,一定要使用自己系统中定义的名称,如果使用用户(攻击者)的入参进行响应,存在风险。如果代理服务器将攻击者的分割响应挂起(缓存),攻击者再次进行请求的时候会导致用户的下一次响应的缓存命中,这样风险很大,可能导致用户浏览器数据泄露给攻击者
    //设置响应头入参时,一定要使用自己系统中的可靠参数
    response.setHeader("Content-disposition","attachment;fileName=" + fileInfo.getFileName());
}

附上这个漏洞的原理及攻击方式链接

https://www.doit.com.cn/article/2011-10-14/3422894.shtml

感谢这位大神的解答。其实就是代理服务器将攻击者的响应缓存(挂起)后,攻击者再次请求,导致用户的响应缓存命中。但也并不是代理服务器就一定会让攻击者如愿哈。不过也不能把自己的工资放在别人手里攥着。。所以,不要直接响应用户入参,不要直接响应用户入参,不要直接响应用户入参。

你可能感兴趣的:(日常工作)