這兩天開(kāi)發(fā)一個(gè)app遇到了上傳文件的安全問(wèn)題,在這里記錄下來(lái),彌補(bǔ)自己只有魚(yú)的記憶的缺陷,也希望有人能夠提供更好的思路去解決文件上傳的安全問(wèn)題.
下面這個(gè)類是文件上傳的公共方法,ToolUtils判斷的是文件的類型(jpg/png等),這樣的做法根本不能避免上傳的文件不是木馬.下面引入兩種方式,調(diào)用時(shí)候只需要引用一種即可.
private String executeUpload(String uploadDir,MultipartFile file) throws Exception {
// 文件后綴名
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
// 判斷后綴名是否合法
String suffixs = suffix.substring(1, suffix.length());
boolean isImage = ToolUtils.isImage(suffixs);
if(!isImage) {
logger.error("the transfer file is not a image!");
throw new FileException("上傳非法文件!");
}
// 上傳文件名
String fileName = UUID.randomUUID() + suffix;
InputStream inputStream = file.getInputStream();
// 第二種,判斷文件是否含有木馬(讀取流)
// boolean flag = FileUtil.isFile(inputStream);
// if(!flag) {
// logger.error("the transfer file is not a image!");
// throw new FileException("上傳非法文件!");
// }
// 服務(wù)器端保存的文件對(duì)象
// 第一種重寫(xiě)圖片引入
try {
ImageUtil.resize1(inputStream, fileName, uploadDir);
} catch (Exception e) {
logger.error("the transfer file is not a image!");
throw new FileException("上傳非法文件!");
}
// File serverFile = new File(uploadDir + fileName);
// 將上傳的文件寫(xiě)入到服務(wù)器端文件內(nèi)
// file.transferTo(serverFile);
return fileName;
}
第一種是將出入的圖片重寫(xiě),實(shí)踐證明,不是圖片的文件會(huì)直接報(bào)錯(cuò),然后在executeUpload中被捕獲.是圖片但有腳本文件的文件會(huì)被重寫(xiě),腳本文件會(huì)被移除.
* public class ImageUtil {
public static void resize1(InputStream inputStream, String fileName, String uploadDir) throws Exception {
if (inputStream == null) {
return;
}
BufferedImage src = ImageIO.read(inputStream);
int old_w = src.getWidth();
// 得到源圖寬
int old_h = src.getHeight();
// 得到源圖長(zhǎng)
BufferedImage newImg = null;
// 判斷輸入圖片的類型
switch (src.getType()) {
case 13:
// png,gif
newImg = new BufferedImage(old_w, old_h, BufferedImage.TYPE_4BYTE_ABGR);
break;
default:
newImg = new BufferedImage(old_w, old_h, BufferedImage.TYPE_INT_RGB);
break;
}
Graphics2D g = newImg.createGraphics();
// 從原圖上取顏色繪制新圖
g.drawImage(src, 0, 0, old_w, old_h, null);
g.dispose();
// 根據(jù)圖片尺寸壓縮比得到新圖的尺寸
newImg.getGraphics().drawImage(
src.getScaledInstance(old_w, old_h, Image.SCALE_SMOOTH), 0,0, null);
File newFile = new File(uploadDir+fileName);
String endName = fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();
ImageIO.write(newImg, endName, newFile);
}
}
第二種是將圖片流轉(zhuǎn)換成十六進(jìn)制的string字符進(jìn)行過(guò)濾,分辨是否含有高危字符.
希望以上代碼對(duì)您有幫助,也希望留下您對(duì)這方面更好的理解.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。