在开发中,经常会有上传文件的需求,为了安全起见,防止上传恶意文件,需要对文件类型进行检查。网上一般有两种方式:
1、对文件扩展名进行检查,符合指定扩展名的文件才可以上传成功
2、对文件头进行检查,文件头的魔数符合预期(每种文件的魔数都是已知的),才可以上传成功
第1种方式有明显的缺陷,用户可以通过修改扩展名来通过检查,
第2种方式可以满足绝大多数场景,但是也有缺点,它不去判断文件扩展名
jmimemagic就是利用文件头中的魔数来判断文件类型的开源工具。
其地址见:https://github.com/arimus/jmimemagic.git
其获取文件类型流程如下:
说明:
1、整个过程中,涉及几个重要的类:
a、Magic:jmimeMagic工具对外交互接口类,类中方法都是static方法。主要的方法有:getMagicMatch(File, boolean)、getMagicMatch(File, boolean, boolean)
b、MagicParser:magic.xml文件解析类,将magic.xml中的数据解析为内部对象,底层解析使用到SAXParse。
c、MagicMatch:magic.xml文件中match标签对应的对象
d、MagicMatcher:将文件和MagicMatch关联起来的工具类
2、左侧虚线框主要加载解析magic.xml文件,解析的结果就是MagicMatcher列表和hintMap列表
a、 magic.xml的代码片段如下:
<match>
<mimetype></mimetype>
<extension></extension>
<description>b, 32 kBits</description>
<property name="bitrate" value="32"/>
<test type="byte" offset="2" length="" bitmask="0xf0" comparator="=">0x10</test>
</match>
每一个match标签对解析后得到一个MagicMatch对象,一个MagicMatch对象存放在MagicMatcher对象中。
b、类MagicMacth的属性如下:
private String mimeType = null;
private String extension = null;
private String description = null;
private ByteBuffer test = null;
private int offset = 0;
private int length = 0;
// possible types:
// byte, short, long, string, date, beshort, belong, bedate, leshort,
// lelong, ledate, regex
private String type = "";
private long bitmask = 0xFFFFFFFFL;
private char comparator = '\0';
private List<MagicMatch> subMatches = new ArrayList<MagicMatch>(0);
private Map<String,String> properties;
3、右侧的虚线框主要是根据文件获取MagicMatch
a、如果传入方法Magic#getMagicMatch的参数extHints=true,那么优先使用文件扩展名去获取MagicMatch,只有根据文件扩展名获取不到MagicMatch的情况下,才会遍历整个matchers去获取对应的MagicMatch。因此,一般extHints的入参值为true。
b、特殊情况下,获取不到MagicMatch,就会抛出异常。
4、测试代码:
public class TestMagic {
public static void main(String[] args) {
MagicMatch magicMatch;
try {
magicMatch = Magic.getMagicMatch(new File("/home/yangjianzhou/document/123456.png"), false);
} catch (Exception exp) {
exp.printStackTrace();
return;
}
String mimeType = magicMatch.getMimeType();
System.out.println("file mime type is : " + mimeType);
}
}
总结:
jmimeMagic是一个很好的获取文件mimeType的工具类,对于大多数文件来说,都可以判断出其文件mimeType,如果不能判断,则可以对magic.xml进行扩展使其满足要求。但是,如果在文件尾部人为写入一些内容,可以躲过该工具的检测。
在本文开始提到过,可以使用扩展名或者文件头来判断文件类型,但是各有优劣,我们可以联合两种方式来判断:首先判断扩展名,在扩展名满足要求的情况下,再检测文件头,如果文件头检测通过,即使文件中被写入恶意代码,这些恶意代码也不会执行。
相关推荐
"MagicMatch.7z"这个压缩包文件包含了用于识别文件类型的工具,主要涉及到`jmimemagic.jar`库,以及其中的`MagicMatch`和`Magic`类。接下来,我们将深入探讨这些知识点。 首先,`jmimemagic.jar`是一个Java库,专门...
总之,jMimeMagic是Java开发者的一个强大工具,它简化了文件类型检测的过程,提高了应用程序的安全性和兼容性。通过开源社区的支持和持续更新,这个库不断改进,满足了日益复杂的文件处理需求。
在Http请求中,有时需要知道Content-Type类型,尤其是上传文件时,更为重要,虽然有些办法可以解决,但都不太准确或者繁琐.jMimeMagic是一个用来检测文件或者数据流的 MIME 类型的 Java 类库。 最新版本是V 0.1.2。...
在本示例中,扫描磁盘并创建索引需要递归遍历指定目录下的全部文件,并标识已经处理的文件以提升效率,在文件类型判断中使用jmimemagic库来判断文件类型。 本示例代码提供了一个完整的 Springboot 集成 ES 实现磁盘...
2. **幻数检测**:除了文件扩展名,jmMimetypeLib还支持检查文件的前几个字节,以识别那些仅依赖扩展名无法准确判断的文件类型。 3. **流处理能力**:该库不仅适用于本地文件,还能处理在网络中流动的数据,如HTTP...
jmimemagic-0.1.0.jar 图片类型自动识别