目录遍历与文件读取漏洞

一些网站的业务需求,可能提供文件查看或下载功能,如果对用户查看或下载的文件不做限制,那么用户就能够查看和下载任意文件,可以使源代码文件、敏感文件等。

详细描述

    目录遍历是通过操作URL强行访问web目录以外的文件,目录和命令,攻击者可以在目标机器的任何位置访问文件,执行命令。

    最基本的目录遍历攻击技术是在URL中使用"../"序列,改变访问资源的路径,访问到web目录以外的文件。

例如:

http://example.com/../../../../some/file

http://example.com/..%255c..%255c/some/file

正常请求为:

http://example.com/test.cgi?look=intex.html

如果存在目录遍历漏洞,攻击者可以访问

http://example.com/test.cgi?look=test.cgi

解决办法

过滤请求数据中"../"字符序列及其各种变形。

验证用户请求中提交的需要访问的文件是否在限定的范围内

验证用户请求中提交的需要访问的文件是否在限定的范围内。



例如:一个下载指定文件夹下名为“readme.txt”文件的链接

http://localhost:8080/zftal-hrm/iframeweb/recruitinfo_downloadHelp.html?fileName=readme.txt

在没有做处理的情况下,将fileName=../css/hrm.css

此时,该链接将会下载上一层文件夹下的css/hrm.css文件

解决方式:验证用户请求中提交的需要访问的文件是否在限定的范围内。

public String downloadHelp() throws UnsupportedEncodingException, FileNotFoundException{
    	String fileName=getString("fileName");
    	boolean isExists=false;
    	String  folderPath= Struts2Utils.getSession().getServletContext().getRealPath("JXNCdownload");
    	File folder = new File(folderPath);
    	//验证用户请求中提交的需要访问的文件是否在限定的范围内,防止访问服务器上任意文件的漏洞
    	if(folder.exists() && folder.isDirectory()){
    		File[] files = folder.listFiles();
    		for(File tempFile:files){
    			if(tempFile.getName().equals(fileName)){
    				isExists=true;
    				break;
    			}
    		}
    	}
    	if(isExists){//如果文件不在指定的“JXNCdownload”文件夹下,则不下载文件
        	if(StringUtil.isNotEmpty(fileName)){
                // 读到流中
                InputStream inStream = new FileInputStream(folderPath+File.separator+fileName);// 文件的存放路径
                getResponse().reset();
                getResponse().setCharacterEncoding("utf-8");
                getResponse().setContentType("application/file");
                String useragent = getRequest().getHeader("user-agent");
                String disposition = DownloadFilenameUtil.fileDisposition(useragent, fileName);
                getResponse().setHeader("Content-Disposition", disposition);
                
                // 循环取出流中的数据
                byte[] b = new byte[100];
                int len;
                try {
                    while ((len = inStream.read(b)) > 0)
                    	getResponse().getOutputStream().write(b, 0, len);
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        	}
    	}
    	return null;
    }


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值