java文件上传漏洞修复工具类

阅读: 评论:0

java文件上传漏洞修复工具类

java文件上传漏洞修复工具类

一、前言

最近安全人员测试系统,说文件上传接口有安全漏洞;

因为文件流是前端传给后台的,说是如果不校验格式的话、会有各种问题。

再此总结下工具类方法。

二、代码

1.常量类

import java.util.Arrays;
import java.util.List;public class FileTypeContants {public static final String FILE_OFFICE = "office";//Word、Excel、PPTpublic static final String FILE_IMG = "img";//图片public static final String FILE_AUDIO = "audio";//音频public static final String FILE_VEDIO = "vedio";//视频public static final String FILE_PDF = "pdf";//pdfpublic static final String FILE_SUFFIX_ERROR	= "文件后缀不正确或文件不存在";public static final String FILE_TYPE_ERROR	= "文件类型不正确";public static final String FILE_HEADER_ERROR	= "文件头不正确";public static final String FILE_SIZE_ERROR	= "文件过大";//Word、Excel、PPT 文件后缀public static final List<String> FILE_SUFFIX_OFFICE = Arrays.asList("doc","docx", "xls","xlsx","ppt","pptx");//图片 文件后缀public static final List<String> FILE_SUFFIX_IMG = Arrays.asList("png","jpeg","jpg");//音频 文件后缀(目前视频只支持MP3)public static final List<String> FILE_SUFFIX_AUDIO = Arrays.asList("mp3");//视频 文件后缀(目前视频只支持MP4)public static final List<String> FILE_SUFFIX_VEDIO = Arrays.asList("mp4");//PDF 文件后缀public static final List<String> FILE_SUFFIX_PDF = Arrays.asList("pdf");//Word、Excel、PPT 文件类型public static final List<String> FILE_TYPE_OFFICE = Arrays.asList("application/msword",//doc"application/vnd.openxmlformats-officedocument.wordprocessingml.document",//docx"application/vnd.ms-excel",//xls"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",//xlsx"application/vnd.ms-powerpoint",//ppt"application/vnd.openxmlformats-officedocument.presentationml.presentation"//pptx);//图片 文件类型public static final List<String> FILE_TYPE_IMG = Arrays.asList("image/png","image/jpeg");//jpeg jpg 是一样的//音频 文件类型public static final List<String> FILE_TYPE_AUDIO = Arrays.asList("audio/mpeg");  //视频 文件类型public static final List<String> FILE_TYPE_VEDIO = Arrays.asList("video/mp4"); //pdf 文件类型public static final List<String> FILE_TYPE_PDF = Arrays.asList("application/pdf");//不同类型文件的文件头判断长度不一样//Word、Excel、PPT 文件头public static final String FILE_HEADER_OFFICE = "D0CF11E0";//doc、xls、pptpublic static final String FILE_HEADER_OFFICEX = "504B0304";//docx、xlsx、pptx//图片 文件头public static final String FILE_HEADER_PNG = "89504E47";public static final String FILE_HEADER_JPG = "FFD8FF";//jpeg jpg 是一样的//音频 文件头public static final String FILE_HEADER_MP3 = "494433";/*** 	MP4 文件头有很多种,先只取 000000*  00 00 00 14 66 74 79 70 69 73 6f 6d00 00 00 18 66 74 79 7000 00 00 1c 66 74 79 7000 00 00 20 66 74 79 70 4d 34 41*/public static final String FILE_HEADER_MP4 = "000000";//pdf 文件头public static final String FILE_HEADER_PDF = "25504446";//Word、Excel、PPT 文件大小public static final long FILE_MAXSIZE_OFFICE = 30 * 1024 ;	// Word/Excel/PPT 都限制30M//图片 大小public static final long FILE_MAXSIZE_IMG = 10 * 1024;//图片限制10M//音频 文件大小public static final long FILE_MAXSIZE_AUDIO = 30 * 1024;//MP3限制30M//视频 文件大小public static final long FILE_MAXSIZE_VEDIO = 2 * 1024 * 1024;//MP4限制2G//pdf 文件大小public static final long FILE_MAXSIZE_PDF = 20 * 1024;//PDF限制10M//其他备用public static final String FILE_TYPE_JSON = "application/json";public static final String FILE_TYPE_XML = "application/xml";public static final String FILE_TYPE_SVG = "image/svg";  
}

说明:
这个是常量类,后续util工具类会用这些常量。

2.工具类

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;@Component
public class FileTypeUtil {/*** 判断文件是否符合要求* 文件后缀、文件类型、文件头、文件大小* @param file* @param fileType* @return*/public static String checkSafeMultipartFile(MultipartFile file, fileTypes){if(file != null && fileTypes != null && fileTypes.length > 0){//文件后缀String fileName = OriginalFilename();Integer index = fileName.lastIndexOf(".");String suffix = fileName.substring(index+1).toLowerCase();//文件大小long fileSize = Size()/1024;//文件类型String fileContentType = ContentType();//文件头String fileHeader = FileHeader(file);for(String fileType : fileTypes){if(FileTypeContants.FILE_OFFICE.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//Word、Excel、PPTreturn FileTypeUtil.checkOffice(fileSize,fileContentType,fileHeader);}else if(FileTypeContants.FILE_IMG.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//图片return FileTypeUtil.checkImg(fileSize,fileContentType,fileHeader);}else if(FileTypeContants.FILE_AUDIO.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//音频return FileTypeUtil.checkAudio(fileSize,fileContentType,fileHeader);}else if(FileTypeContants.FILE_VEDIO.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//视频return FileTypeUtil.checkVedio(fileSize,fileContentType,fileHeader);}else if(FileTypeContants.FILE_PDF.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//PDFreturn FileTypeUtil.checkPDF(fileSize,fileContentType,fileHeader);}}}return FileTypeContants.FILE_SUFFIX_ERROR;}public static String checkSafeNormalFile(File file, fileTypes){if(file != null && fileTypes != null && ists() && fileTypes.length > 0){//文件后缀String fileName = Name();Integer index = fileName.lastIndexOf(".");String suffix = fileName.substring(index+1).toLowerCase();//文件大小long fileSize = file.length()/1024;//文件类型,普通文件没有这个//String fileContentType = ContentType();//文件头String fileHeader = NormalFileHeader(file);for(String fileType : fileTypes){if(FileTypeContants.FILE_OFFICE.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//Word、Excel、PPTreturn FileTypeUtil.checkOffice(fileSize, fileHeader);}else if(FileTypeContants.FILE_IMG.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//图片return FileTypeUtil.checkImg(fileSize, fileHeader);}else if(FileTypeContants.FILE_AUDIO.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//音频return FileTypeUtil.checkAudio(fileSize, fileHeader);}else if(FileTypeContants.FILE_VEDIO.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//视频return FileTypeUtil.checkVedio(fileSize, fileHeader);}else if(FileTypeContants.FILE_PDF.equals(fileType) && FileTypeContants.FILE_ains(suffix)){//PDFreturn FileTypeUtil.checkPDF(fileSize, fileHeader);}}}return FileTypeContants.FILE_SUFFIX_ERROR;}/*** 判断文件是否符合要求,多个文件* 文件后缀、文件类型、文件头、文件大小* @param files* @param fileTypes* @return*/public static String checkSafeMultipartFiles(MultipartFile[] files, fileTypes){String checkMessage = "";for(MultipartFile file : files){checkMessage = FileTypeUtil.checkSafeMultipartFile(file, fileTypes);if(!"".equals(checkMessage)){return checkMessage;}}return checkMessage;}/*** 判断 Word、Excel、PPT* @param fileSize* @param fileContentType* @param fileHeader* @return*/public static String checkOffice(long fileSize,String fileContentType ,String fileHeader){//判断文件类型if(!FileTypeContants.FILE_ains(fileContentType)){return FileTypeContants.FILE_TYPE_ERROR;}//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_OFFICE) && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_OFFICEX)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_OFFICE){return FileTypeContants.FILE_SIZE_ERROR;}return "";}public static String checkOffice(long fileSize, String fileHeader){//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_OFFICE)&& !fileHeader.startsWith(FileTypeContants.FILE_HEADER_OFFICEX)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_OFFICE){return FileTypeContants.FILE_SIZE_ERROR;}return "";}/*** 判断图片* @param fileSize* @param fileContentType* @param fileHeader* @return*/public static String checkImg(long fileSize, String fileContentType, String fileHeader){//判断文件类型    	if(!FileTypeContants.FILE_ains(fileContentType)){return FileTypeContants.FILE_TYPE_ERROR;}//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_PNG) && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_JPG)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_IMG){return FileTypeContants.FILE_SIZE_ERROR;}return "";}public static String checkImg(long fileSize, String fileHeader){//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_PNG)&& !fileHeader.startsWith(FileTypeContants.FILE_HEADER_JPG)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_IMG){return FileTypeContants.FILE_SIZE_ERROR;}return "";}/*** 判断音频* @param fileSize* @param fileContentType* @param fileHeader* @return*/public static String checkAudio(long fileSize, String fileContentType, String fileHeader){//判断文件类型if(!FileTypeContants.FILE_ains(fileContentType)){return FileTypeContants.FILE_TYPE_ERROR;}//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_MP3)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_AUDIO){return FileTypeContants.FILE_SIZE_ERROR;}return "";}public static String checkAudio(long fileSize, String fileHeader){//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_MP3)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_AUDIO){return FileTypeContants.FILE_SIZE_ERROR;}return "";}/*** 判断视频* @param fileSize* @param fileContentType* @param fileHeader* @return*/public static String checkVedio(long fileSize, String fileContentType, String fileHeader){//判断文件类型if(!FileTypeContants.FILE_ains(fileContentType)){return FileTypeContants.FILE_TYPE_ERROR;}//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_MP4)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_VEDIO){return FileTypeContants.FILE_SIZE_ERROR;}return "";}public static String checkVedio(long fileSize, String fileHeader){//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_MP4)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_VEDIO){return FileTypeContants.FILE_SIZE_ERROR;}return "";}/*** 判断PDF* @param fileSize* @param fileContentType* @param fileHeader* @return*/public static String checkPDF(long fileSize,String fileContentType, String fileHeader){//判断文件类型if(!FileTypeContants.FILE_ains(fileContentType)){return FileTypeContants.FILE_TYPE_ERROR;}//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_PDF)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_PDF){return FileTypeContants.FILE_SIZE_ERROR;}return "";}public static String checkPDF(long fileSize, String fileHeader){//判断文件头if(fileHeader !=null && !fileHeader.startsWith(FileTypeContants.FILE_HEADER_PDF)){return FileTypeContants.FILE_HEADER_ERROR;}//判断文件大小if(fileSize > FileTypeContants.FILE_MAXSIZE_PDF){return FileTypeContants.FILE_SIZE_ERROR;}return "";}/*** 根据文件路径获取文件头信息** @param filePath*            文件路径* @return 文件头信息*/public static String getFileHeader(MultipartFile file) {InputStream is = null;String value = "";try {is = InputStream();byte[] b = new byte[16];is.read(b, 0, b.length);value = bytesToHexString(b);} catch (Exception e) {e.printStackTrace();} finally {if (null != is) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}return value;}public static String getNormalFileHeader(File file) {InputStream is = null;String value = "";try {is = new FileInputStream(file);byte[] b = new byte[16];is.read(b, 0, b.length);value = bytesToHexString(b);} catch (Exception e) {e.printStackTrace();} finally {if (null != is) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}return value;}/*** 将要读取文件头信息的文件的byte数组转换成string类型表示** @param src*            要读取文件头信息的文件的byte数组* @return 文件头十六进制信息*/private static String bytesToHexString(byte[] src) {StringBuilder builder = new StringBuilder();if (src == null || src.length <= 0) {return null;}String hv;for (int i = 0; i < src.length; i++) {// 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写hv = HexString(src[i] & 0xFF).toUpperCase();if (hv.length() < 2) {builder.append(0);}builder.append(hv);}System.out.println("HexString: " + String());String();}
}

说明:
1.checkSafeMultipartFile方法,用来判断入参是MultipartFile的文件是否符合要求

2.checkSafeMultipartFiles方法,用来判断入参是MultipartFile数组的文件是否符合要求

3.调用这些工具方法后,会检查文件后缀是否符合要求、文件大小是否符合要求、文件流中的格式是否与文件名中的格式对应等,如果不符合要求,就返回错误信息;如果符合要求,就返回空字符串

4.可以看常量类,目前只允许word/excel/ppt/pdf/mp3/mp4等文件上传,可以自己根据需要扩展

3.使用样例代码

    @PostMapping("/mycontroller/oneUpload")public JSONObject OneExport(@RequestParam("file") MultipartFile file,@RequestParam String type) throws Exception {JSONObject backJson = new JSONObject();//文件必须是 word/excel/ppt/pdf/mp3/mp4String checkFile = FileTypeUtil.checkSafeMultipartFile(file, FileTypeContants.FILE_OFFICE, FileTypeContants.FILE_IMG, FileTypeContants.FILE_PDF,FileTypeContants.FILE_AUDIO, FileTypeContants.FILE_VEDIO);if(!"".equals(checkFile)) {backJson.put("code", "-1");backJson.put("msg", "上传文件格式异常,请重新确认:" + checkFile);throw new Exception("上传文件格式异常,请重新确认:" + checkFile);}......return backJson;}

说明:
假设上传文件页面,前端传来了要上传的文件MultipartFile file,先使用工具方法校验,如果目标文件不符合要求,那就报错,不允许上传;如果符合要求,那么才能执行后续的上传操作。

本文发布于:2024-01-27 23:43:50,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063702313362.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23