任意文件上传漏洞,添加白名单校验

为解决任意文件上传漏洞,添加白名单校验文件后缀名
1)添加配置信息

file_strict_name=true
file_special_characters=
file_allow_types=jpg,png,tif,gif,dwg,pdf,zip,docx,doc,xls,xlsx
file_allows=true

2)添加白名单校验方法

@Service
public class ObsService {
	
	/**
	 * 是否要判断文件名含有非法字符
	 */
	@Value("${file_strict_name}")
    private String fileStrictName;
	/**
	 * 文件名含有的特殊字符
	 */
    @Value("${file_special_characters}")
    private String fileSpecialCharacters;
    
    /**
	 * 允许上传的文件类型
	 */
    @Value("${file_allow_types}")
    private String[] fileAllowTypes;
    /**
	 * 是否开启文件类型白名单
	 */
	@Value("${file_allows}")
    private String fileAllows;
	
	
	/**
	 * 判断文件名中是否含有非法字符
	 * @param fileName
	 */
	public void illegalCharacters(String fileName) throws Exception{
		if(StringUtils.isNotBlank(fileStrictName) && Boolean.valueOf(fileStrictName)) {
			//要判断文件名中是否包含非法字符
			if(StringUtils.isNotBlank(fileName)) {
				//默认允许包含中文、英文、数字包括下划线
				String n = "[\\u4E00-\\u9FA5A-Za-z0-9_]+";
				//不为空则拼接上
				if (null != fileSpecialCharacters && !"".equals(fileSpecialCharacters)) {
					n = "[\\u4E00-\\u9FA5A-Za-z0-9_" + fileSpecialCharacters+"]+"; 
				}
				Pattern pattern = Pattern.compile(n); 
				String nn = fileName;
				int last = nn.lastIndexOf(".");
				if (last != -1) {
					//截取掉扩展名好判断一些
					nn = nn.substring(0,last);
					
				}
				Matcher mat = pattern.matcher(nn); 
				if(!mat.matches()){
					throw new RuntimeException("文件名包含非法的字符,文件名允许输入【汉字,汉字标点符号,字母,数字,下划线,空格】");
				}
			}
		}
	}
	
	/**
	 * 上传文件类型是否在白名单中
	 * @param fileName
	 */
	public void whiteListVerify(String fileName) throws Exception{
		if(StringUtils.isNotBlank(fileAllows) && Boolean.valueOf(fileAllows)) {
			if(StringUtils.isNotBlank(fileName)) {
				String nn = fileName;
				int last = nn.lastIndexOf(".");
				if (last != -1) {
					//截取掉扩展名好判断一些
					nn = nn.substring(last+1, nn.length());
				}
				if(fileAllowTypes != null) {
					List<String> fileAllowsList = Arrays.asList(fileAllowTypes);
					if(!fileAllowsList.contains(nn.toLowerCase())) {
						throw new RuntimeException("文件【"+fileName+"】格式不正确,请上传["+StringUtils.join(fileAllowTypes, ",")+"]格式的文件");
					}
				}
			}
		}
	}
	
}

3)在文件上传接口中,调用白名单校验接口

@PostMapping("putFile")
	@Transactional
	public void putObject(HttpServletRequest request) throws Exception {
		List<MultipartFile> files = ((MultipartHttpServletRequest)request).getFiles("name");
		String businessType = request.getParameter("businessType");
		String businessMid = request.getParameter("businessKey");
		Attachments attachments = null;
		for(MultipartFile file: files) {
			try {
				//设置文件业务信息
				String fileName = file.getOriginalFilename();
				
				try {
					//判断文件名中是否含有非法字符
					obsService.illegalCharacters(fileName);
					//文件类型是否包含在白名单中
					obsService.whiteListVerify(fileName);
				}catch (Exception e1) {
					// TODO: handle exception
					throw e1;
				}
				
				......
			} catch (Exception e) {
				log.error("文件上传失败", e);
				throw e;
			}
		}
	}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值