后缀判断的隐患:
对于判断前端(或网络)发送过来文件的类型,有些同学第一个想到的可能就是:根据其后缀名进行格式的判断。。。
正常情况下,是可以这样做。但实际上,任何文件的后缀都可以随意命名,因此仅通过后缀名判断其文件格式是不安全的。
如果有人将奇奇怪怪的文件后缀名改成你认为合法的后缀调用你的接口,那么你的服务器就变成了别人的网盘。
Solution:
- 我们可以根据文件头判断文件的格式。
- 什么是文件头(百度百科)
常见的图片的文件头(包括但不限于):
文件类型 | 文件头(这里是16进制) |
png | 89504E47 |
jpg | FFD8FFE0 / FFD8FFE1 / FFD8FFE8 |
tif | 49492A00 |
- 其他文件类型文件头链接分享:
java获取文件头方法:
/**
* 获取文件头
* @param file 文件
* @return value of fileHeader(Hex)
*/
public String getFileHeader( MultipartFile file) {
InputStream is = null;
String value = null;
try {
is = file.getInputStream();
byte[] b = new byte[4];
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;
}
private String bytesToHexString(byte[] src) {
StringBuilder builder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
String hv;
for (byte b : src) {
hv = Integer.toHexString(b & 0xFF).toUpperCase();
if (hv.length() < 2) {
builder.append(0);
}
builder.append(hv);
}
return builder.toString();
}