文件下载功能不安全实现造成的文件读取问题也没什么大说特说的(其他语言也雷同),通常情况是,外部参数不安全引用到功能内部实现的路径中(简单点讲,就是下载路径可被外部直接控制)。但这里Struts2提供下载文件名的动态参数绑定配置,导致这个安全问题更容易发生!
看看实际情况,使用baidu搜索引擎key的结果: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外部参数的自动表单填充特性的使用,这绝对是最简流程的实现代码了(正常的开发者,谁会去多写几行代码啊!),且这是个通用功能了!
另外,注意到:
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心里不爽....