小心Commons fileupload攻击[更新]

1.这种攻击不会出现在BS的应用中,因为要从web页面模拟攻击比较累。而CS程序则天生可能会隐藏这种问题。

 

2.经过认真的跟进,最终发现问题出在sizeThreshold 这个参数上。

 

让人费解的来由是:

org.apache.commons.fileupload.FileUploadBase这个基类351行,解析request调用了

 

OutputStream os = item.getOutputStream();

 

跟进去看方法实现:

    public OutputStream getOutputStream()
        throws IOException {
        if (dfos == null) {
            File outputFile = getTempFile();
            dfos = new DeferredFileOutputStream(sizeThreshold, outputFile);
        }
        return dfos;
    }

 再进去看getTempFile,发现这里创建了文件

 

    protected File getTempFile() {
        File tempDir = repository;
        if (tempDir == null) {
            tempDir = new File(System.getProperty("java.io.tmpdir"));
        }

        String fileName = "upload_" + UID + "_" + getUniqueId() + ".tmp";

        File f = new File(tempDir, fileName);
        FileCleaner.track(f, this);
        return f;
    }

 

也就是只要使用了fileupload组件,就会走到 getTempFile,就会创建临时文件。而文档中提到的sizeThreshold根本无用(确实整个代码跟进的过程中,sizeThreshold都没有使用到)

 

 

那么真实情况如何?

 

1.下面这句并不会真的在磁盘创建文件。。也是久疏基础知识,让自己的推理陷入了误区。

File f = new File(tempDir, fileName);

 2.sizeThreshold这个参数(The threshold above which uploads will be stored on disk.)起作用的地方并不在common.fileupload这个项目中,而是上面getOutputStream这段代码中,将这个参数传到了common.io这个项目中的实现类。也就是项目依赖。

 dfos = new DeferredFileOutputStream(sizeThreshold, outputFile);

 

 

 

-------------------------原帖分界线----------------------------------

最近搞人的一桩事情:

 

 

严重: Socket accept failed
java.net.SocketException: Too many open files
	at java.net.PlainSocketImpl.socketAccept(Native Method)
	at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384)
	at java.net.ServerSocket.implAccept(ServerSocket.java:453)
	at java.net.ServerSocket.accept(ServerSocket.java:421)
	at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61)
	at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:310)
	at java.lang.Thread.run(Thread.java:619)

 

排查很久才发现,竟然是文件上传这个地方的问题。无论有意还是恶意,都会让人恼火。

 

有些客户端故意使用multi-part封装全部参数, 比如"abc=111"的普通参数,经过包装后post,成了multi-part。 这样就绕过Jakarta Commons Fileupload的判断逻辑:

 

具体的恶劣方式如下:

1.给一个request带上20+个参数,全部变成mutiparty+ post提交。给服务器带来大量的临时文件创建、删除压力。

2.大量的请求耗时较长的接口。当linux下文件句柄消耗完, 服务停止响应。

 

 

可考虑的解决方式??

1.限制上传文件的类型, 非常有必要.

2.升级commons.fileupload 到1.2+,后面的版本有提供新的接口处理这个bug

3.改造MultiPartRequest,根据业务限制每个request带的FileItem个数。基本限制到1-2个即可。超出立即丢弃。

  • 大小: 14.2 KB
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值