本文出自冯立彬的博客
,原地址:http://www.fenglibin.com/use_java_to_check_images_type_and_security.html
一、通常情况下,验证一个文件是否图片,可以通过以下三种方式:
1)、判断文件的扩展名是否是要求的图片扩展名
这种判断是用得比较多的一种方式,不过这种方式非常的不妥,别人稍微的把一个不是图片的文件的扩展名修改为图片的扩展名,就绕开了你的这种校验,如果这上传的文件是shell、php或者jsp,那你的网站基本上可以说就在别人的手里面了。
不过这种判断方式也不是完全没有用,我们可以把它放在判断图片的最外层,如果一个文件连扩展名都不是我们所要求的图片扩展名,那就根本不用后面的内
容格式检查了,从一定程度上说,对减少服务器的压力还是有一定的帮助,否则所有的文件都等上传完后成后再通过服务器去判断,那会在一定程度上浪费器资源
的。
2)、根据文件的前面几个字节,即常说的魔术数字进行判断,不同文件类型的开头几个字节,可以查看我的另外一篇专站介绍:表示不同文件类型的魔术数字
。
但是这种判断方式也是非常不靠谱的,因为他只能够验证文件的前面几个字节,如此时有人把一个可执行的PHP文件的扩展名修改为PNG,然后再在前面补上”89 50″两个字节,就又绕开了这种验证方式。
以下是一段通过JAVA代码获取文件前面两个字节的示例程序:
-
import
java.io.File;
-
import
java.io.FileInputStream;
-
import
java.io.IOException;
-
import
java.io.InputStream;
-
-
public
class
ImageTypeCheck {
-
-
public
static
String bytesToHexString(
byte
[] src) {
-
StringBuilder stringBuilder = new
StringBuilder();
-
if
(src ==
null
|| src.length <=
0
) {
-
return
null
;
-
}
-
for
(
int
i =
0
; i < src.length; i++) {
-
int
v = src[i] &
0xFF
;
-
String hv = Integer.toHexString(v);
-
if
(hv.length() <
2
) {
-
stringBuilder.append(0
);
-
}
-
stringBuilder.append(hv);
-
}
-
return
stringBuilder.toString();
-
}
-
public
static
void
main(String[] args)
throws
IOException {
-
String imagePath = "c:/favicon.png"
;
-
File image = new
File(imagePath);
-
InputStream is = new
FileInputStream(image);
-
byte
[] bt =
new
byte
[
2
];
-
is.read(bt);
-
System.out.println(bytesToHexString(bt));
-
}
-
}
不过这种判断方式和判断扩展名一样,也不是完全没有用,至少可以在前期在简单的检查,为进入下一步检查做铺垫。
3)、获取图片的宽高属性
如果能够正常的获取到一张图片的宽高属性,那肯定这是一张图片,因为非图片文件我们是获取不到它的宽高属性的,以下是用于获取根据是否可以获取到图片宽高属性来判断这是否一张图片的JAVA代码:
-
-
-
-
-
-
-
public
static
boolean
isImage(File imageFile) {
-
if
(!imageFile.exists()) {
-
return
false
;
-
}
-
Image img = null
;
-
try
{
-
img = ImageIO.read(imageFile);
-
if
(img ==
null
|| img.getWidth(
null
) <=
0
|| img.getHeight(
null
) <=
0
) {
-
return
false
;
-
}
-
return
true
;
-
} catch
(Exception e) {
-
return
false
;
-
} finally
{
-
img = null
;
-
}
-
}
二、图片文件的安全检查处理
好了,我们终于判断出一个文件是否图片了,可是如果是在一个可以正常浏览的图片文件中加入一些非法的代码呢:
这就是在一张正常的图片末尾增加的一些iframe代码,我曾经尝试过单独打开这张图片,也将这张图片放于网页上打开,虽然这样都不会被执行,但并不代表插入其它的代码也并不会执行,杀毒软件(如AVAST)对这种修改是会报为病毒的。
那我们要如何预防这种东西,即可以正常打开,又具有正确的图片文件扩展名,还可以获取到它的宽高属性?呵,我们这个时候可以对这个图片进地重写,给它增加
水印或者对它进行resize操作,这样新生成的图片就不会再包含这样的恶意代码了,以下是一个增加水印的JAVA实现:
-
-
-
-
-
-
-
-
-
-
-
public
final
static
void
addWaterMark(String srcImg, String waterImg,
int
x,
int
y,
float
alpha)
throws
IOException {
-
-
File file = new
File(srcImg);
-
String ext = srcImg.substring(srcImg.lastIndexOf("."
) +
1
);
-
Image image = ImageIO.read(file);
-
int
width = image.getWidth(
null
);
-
int
height = image.getHeight(
null
);
-
-
-
BufferedImage bufferedImage = new
BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-
Graphics2D g = bufferedImage.createGraphics();
-
g.drawImage(image, 0
,
0
, width, height,
null
);
-
-
-
Image waterImage = ImageIO.read(new
File(waterImg));
-
int
width_1 = waterImage.getWidth(
null
);
-
int
height_1 = waterImage.getHeight(
null
);
-
-
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
-
-
-
int
widthDiff = width - width_1;
-
int
heightDiff = height - height_1;
-
if
(x <
0
) {
-
x = widthDiff / 2
;
-
} else
if
(x > widthDiff) {
-
x = widthDiff;
-
}
-
if
(y <
0
) {
-
y = heightDiff / 2
;
-
} else
if
(y > heightDiff) {
-
y = heightDiff;
-
}
-
-
-
g.drawImage(waterImage, x, y, width_1, height_1, null
);
-
-
g.dispose();
-
-
-
ImageIO.write(bufferedImage, ext, file);
-
}
通过以上几种方式,应该可以避免绝大部份图片中带恶意代码的安全问题,不过由于我个人的才疏学浅,可能有没有考虑周全的地方,还请各位不吝指教了。
分享到:
相关推荐
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...
50.JAVA语言如何进行异常处理,关键字:thorws,throw,try,catch,finally 51.Object类(或者其子类)的finalize()方法在什么情况下被调用? 52.一个“.java”原文件中是否可以包括多个类(不是内部类)? 53.掌握...
对 MP3 会使用在线播放器进行渲染 剪贴板处理:自动将复制的内容转换为 Markdown 格式;外链的图片自动上传站内 @用户:根据用户名自动补全,支持快捷键 Emoji:支持大部分主流 Emoji 表情,快捷键自动补全 数学...
#### 文件上传可以参考以下安全需求进行处理: 1. 服务器配置: (1)将上传目录和上传文件设置为不可执行, 杜绝脚本执行。 (2)应保证服务器安全,避免文件解析漏洞。 2. 在服务端对上传文件进行检查: (1)使用...
JTopCMS基于JavaEE标准自主...支持自动将图片 视频 文件 以及静态发布html发布到各资源服务器,动静分离,静态前端访问和动态后端访问独立处理,提升性能和安全性。 JTopCMS截图 相关阅读 同类推荐:站长常用源码