背景
服務(wù)器對上傳文件一般進行文件類型的嚴(yán)格限制,防止有惡意文件上傳至服務(wù)器。
一般使用“后綴名”方式去鑒別上傳文件類型卧波,但是該種方式有可能被繞過。
惡意攻擊者通過將非法文件修改為合法的后綴名方式提交文件至服務(wù)器策橘,從而調(diào)用惡意腳本窗悯。
e.g.
通過將.jsp后綴運行文件更改后綴名為.jpg方式偽裝為圖片提交至服務(wù)器,因為服務(wù)端對于圖片格式文件允許運行梦皮,
則導(dǎo)致惡意.jsp源文件得以運行造成影響
解決辦法
服務(wù)器不僅僅需要對文件后綴名進行校驗炭分,同時需要對文件內(nèi)容進行檢測,確保文件類型是該后綴名標(biāo)注的類型!
文件MimeType類型與后綴名參照表剑肯,如下:
http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
tika中參照xml捧毛,如下:
https://github.com/apache/tika/blob/master/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml
工具使用
我們使用apache提供的tika工具進行文件內(nèi)容的檢測工作,tika不僅僅可以作為文件內(nèi)容檢測工具让网,同時其還是一款高效的內(nèi)容提取工具呀忧。
1.maven引入tika的檢測jar
<!-- tika核心包 -->
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>x.x.x</version>
</dependency>
2.示例代碼
/**
* 通過tika工具檢測文件實際類型
*
* @throws IOException IO異常
* @throws MimeTypeException MimeType異常
*/
@Test
public void getMimeTypeTest() throws IOException, MimeTypeException {
// 獲取文件
File gifFile = ResourceUtils.getFile("classpath:files/test.gif");
File jpgFile = ResourceUtils.getFile("classpath:files/test.jpg");
File pngFile = ResourceUtils.getFile("classpath:files/test.png");
File xlsFile = ResourceUtils.getFile("classpath:files/test.xls");
File xlsxFile = ResourceUtils.getFile("classpath:files/test.xlsx");
File docFile = ResourceUtils.getFile("classpath:files/test.doc");
File docxFile = ResourceUtils.getFile("classpath:files/test.docx");
File sqlFile = ResourceUtils.getFile("classpath:files/test.sql");
// 使用tika提供的外觀工具,進行檢測
Tika tika = new Tika();
// 此處檢測文件內(nèi)容,返回文件MimeType名稱
String detect = tika.detect(docFile);
System.out.println("MimeType:" + detect);
// 獲取tika提供的默認(rèn)參照表
// 可以進行自定義,參照https://stackoverflow.com/questions/13650372/how-to-determine-appropriate-file-extension-from-mime-type-in-java
MimeTypes allTypes = MimeTypes.getDefaultMimeTypes();
// 根據(jù)MimeType名稱獲取MimeType類型
MimeType mimeType = allTypes.forName(detect);
// 根據(jù)MimeType類型獲取對應(yīng)的后綴名
String extension = mimeType.getExtension();
System.out.println(extension);
}