mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	阻止任意文件下载漏洞
This commit is contained in:
		@@ -0,0 +1,47 @@
 | 
			
		||||
package com.ruoyi.common.utils.file;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 文件类型工具类
 | 
			
		||||
 *
 | 
			
		||||
 * @author ruoyi
 | 
			
		||||
 */
 | 
			
		||||
public class FileTypeUtils
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取文件类型
 | 
			
		||||
     * <p>
 | 
			
		||||
     * 例如: ruoyi.txt, 返回: txt
 | 
			
		||||
     * 
 | 
			
		||||
     * @param file 文件名
 | 
			
		||||
     * @return 后缀(不含".")
 | 
			
		||||
     */
 | 
			
		||||
    public static String getFileType(File file)
 | 
			
		||||
    {
 | 
			
		||||
        if (null == file)
 | 
			
		||||
        {
 | 
			
		||||
            return StringUtils.EMPTY;
 | 
			
		||||
        }
 | 
			
		||||
        return getFileType(file.getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取文件类型
 | 
			
		||||
     * <p>
 | 
			
		||||
     * 例如: ruoyi.txt, 返回: txt
 | 
			
		||||
     *
 | 
			
		||||
     * @param fileName 文件名
 | 
			
		||||
     * @return 后缀(不含".")
 | 
			
		||||
     */
 | 
			
		||||
    public static String getFileType(String fileName)
 | 
			
		||||
    {
 | 
			
		||||
        int separatorIndex = fileName.lastIndexOf(".");
 | 
			
		||||
        if (separatorIndex < 0)
 | 
			
		||||
        {
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
        return fileName.substring(separatorIndex + 1).toLowerCase();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -7,7 +7,11 @@ import java.io.IOException;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.io.UnsupportedEncodingException;
 | 
			
		||||
import java.net.URLEncoder;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import org.apache.commons.lang3.ArrayUtils;
 | 
			
		||||
import com.ruoyi.common.utils.StringUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 文件处理工具类
 | 
			
		||||
@@ -104,6 +108,30 @@ public class FileUtils extends org.apache.commons.io.FileUtils
 | 
			
		||||
        return filename.matches(FILENAME_PATTERN);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 检查文件是否可下载
 | 
			
		||||
     * 
 | 
			
		||||
     * @param resource 需要下载的文件
 | 
			
		||||
     * @return true 正常 false 非法
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean checkAllowDownload(String resource)
 | 
			
		||||
    {
 | 
			
		||||
        // 禁止目录上跳级别
 | 
			
		||||
        if (StringUtils.contains(resource, ".."))
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 检查允许下载的文件规则
 | 
			
		||||
        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
 | 
			
		||||
        {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 不在允许下载的文件规则
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下载文件名重新编码
 | 
			
		||||
     * 
 | 
			
		||||
@@ -111,8 +139,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils
 | 
			
		||||
     * @param fileName 文件名
 | 
			
		||||
     * @return 编码后的文件名
 | 
			
		||||
     */
 | 
			
		||||
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
 | 
			
		||||
            throws UnsupportedEncodingException
 | 
			
		||||
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
 | 
			
		||||
    {
 | 
			
		||||
        final String agent = request.getHeader("USER-AGENT");
 | 
			
		||||
        String filename = fileName;
 | 
			
		||||
@@ -139,4 +166,38 @@ public class FileUtils extends org.apache.commons.io.FileUtils
 | 
			
		||||
        }
 | 
			
		||||
        return filename;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下载文件名重新编码
 | 
			
		||||
     *
 | 
			
		||||
     * @param response 响应对象
 | 
			
		||||
     * @param realFileName 真实文件名
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
 | 
			
		||||
    {
 | 
			
		||||
        String percentEncodedFileName = percentEncode(realFileName);
 | 
			
		||||
 | 
			
		||||
        StringBuilder contentDispositionValue = new StringBuilder();
 | 
			
		||||
        contentDispositionValue.append("attachment; filename=")
 | 
			
		||||
                .append(percentEncodedFileName)
 | 
			
		||||
                .append(";")
 | 
			
		||||
                .append("filename*=")
 | 
			
		||||
                .append("utf-8''")
 | 
			
		||||
                .append(percentEncodedFileName);
 | 
			
		||||
 | 
			
		||||
        response.setHeader("Content-disposition", contentDispositionValue.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 百分号编码工具方法
 | 
			
		||||
     *
 | 
			
		||||
     * @param s 需要百分号编码的字符串
 | 
			
		||||
     * @return 百分号编码后的字符串
 | 
			
		||||
     */
 | 
			
		||||
    public static String percentEncode(String s) throws UnsupportedEncodingException
 | 
			
		||||
    {
 | 
			
		||||
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
 | 
			
		||||
        return encode.replaceAll("\\+", "%20");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user