Apache Tika无法正确识别MIME类型的解决方案及合规疑问
文件上传时Apache Tika文件类型检测的问题
我在文件上传时使用Apache Tika进行文件类型检测,代码实现如下:
static final List<String> VALID_FILE_TYPES = Arrays.asList( // 省略部分代码 "audio/aac" ); public static void detectFileType(InputStream inputStream, String fileId) { try { ApacheTika tika = new ApacheTika(); String fileTypeFromFile = tika.detect(inputStream); if (!VALID_FILE_TYPES.contains(fileTypeFromFile)) { throw new IllegalFileUploadException("Illegal file type"); } } catch (IOException ex) { // ... } }
但部分文件(如*.acc)被Apache Tika识别为application/octet-stream,现存在两个疑问:
- 是否有方案能正确识别这类文件,获取其准确类型(如audio/aac)?
- 若没有可行方案,是否应将
application/octet-stream加入VALID_FILE_TYPES以接收audio/aac等文件?
问题解答
1. 正确识别文件类型的可行方案
- 升级Tika版本:旧版本对部分格式的支持不完善,升级到最新稳定版,能修复不少识别漏洞。
- 结合文件名检测:不要只用
tika.detect(inputStream),改用tika.detect(inputStream, fileName)方法,让Tika同时参考文件名后缀和文件内容,大幅提升识别准确率——*.acc后缀本身就是AAC格式的标识,结合后能避免单纯靠内容检测的误判。 - 检查文件完整性:确认被误判的*.acc文件是否正常,比如有没有损坏、是否符合标准AAC编码规范。如果文件本身结构异常,Tika自然无法正确识别。
- 添加自定义检测规则:如果以上方法都无效,可以针对AAC文件的特征字节做额外校验。AAC文件开头通常有特定的文件签名(比如ADTS格式的AAC开头是
0xFFF1或0xFFF9),当Tika返回application/octet-stream时,读取文件开头的几个字节匹配特征,符合则判定为audio/aac。
2. 是否应该加入application/octet-stream到白名单
绝对不建议直接把application/octet-stream加入VALID_FILE_TYPES。这个类型是通用二进制文件的兜底标识,涵盖所有Tika识别不出来的文件,一旦加入等于放弃了对这类文件的类型校验,恶意文件很容易伪装成这个类型上传,带来严重的安全风险。
正确的做法是优先用第一点里的方案优化识别准确率,实在有个别文件无法识别,可以单独针对这类文件做“文件名后缀+自定义特征校验”的组合判断,而不是直接放开白名单。
内容的提问来源于stack exchange,提问作者binary
相关产品推荐
相关产品推荐

