文件下载功能不安全实现造成的文件读取问题也没什么大说特说的(其他语言也雷同),通常情况是,外部参数不安全引用到功能内部实现的路径中(简单点讲,就是下载路径可被外部直接控制)。但这里Struts2提供下载文件名的动态参数绑定配置,导致这个安全问题更容易发生!

看看实际情况,使用baidu搜索引擎key的结果:Struts2文件下载,如图:

Struts2文件下载功能不安全实现可能造成的文件读取问题!

在排名第一的教程demo中,可以看到配置文件:

<result type="stream"> 
    <param name="contentType">application/octet-stream</param> 
    <param name="inputName">inputStream</param> 
    <param name="contentDisposition">attachment;filename="${fileName}"</param> 
    <param name="bufferSize">4096</param> 
</result>

下载文件名的动态参数自动填充配置:

<param name="contentDisposition">attachment;filename="${fileName}"</param>

代码实现:

private String fileName;

public void setFileName(String fileName) {
    this.fileName = fileName;
}

public String getFileName() {
    return fileName;
}

public InputStream getInputStream() throws FileNotFoundException {
    return ServletActionContext.getServletContext().getResourceAsStream("/" + fileName);
    // return new FileInputStream("c://"+fileName);
}

ps://Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。这里动态参数配置后,会调用action中filename的属性值,结合struts2外部参数的自动表单填充特性的使用,这绝对是最简流程的实现代码了(正常的开发者,谁会去多写几行代码啊!),且这是个通用功能了!

Struts2文件下载功能不安全实现可能造成的文件读取问题!

另外,注意到:

return ServletActionContext.getServletContext().getResourceAsStream("/" + fileName);

调用Servlet中的对象,使用的是相对路径,只能在本应用内读取文件!

而:

return new FileInputStream("绝对路径"+fileName);

使用FileInputStream,使用的是绝对路径,造成任意文件读取!

//严格讲,除了这个安全问题,这个demo写得还是不错的,简单明了!但也可能让后来者在不少的应用中植入了“后门”!

吐槽吐槽:

1#

小胖子 (我是小胖子,我为z7y代言!!) | 2013-05-15 01:21

这个流弊,马克!

2#

浮生 | 2013-05-15 01:56

这爆的有些犀利,前排水果摊卖苹果喽

3#

裙下的秘密 | 2013-05-15 02:42

前排,瓜子站位

4#

园长 (你在身边就是缘,缘分写在数据库里面。) | 2013-05-15 09:15

像这种demo里面明显存在安全问题的东东在广大的CSDN和ITEYE里面普遍存在的哦,至少我看见多不少了。

5#

园长 (你在身边就是缘,缘分写在数据库里面。) | 2013-05-15 09:17

以前写代码的时候会对安全细节比较重视,现在就算知道有安全问题也不想去处理了。

愿意就是大多数人一天都被迫加班,改各种BUG心里不爽....

source