1. java安全编码指南之:拒绝Denial of Service
简介
DOS不是那个windows的前身,而是Denial of Service,有做过系统安全方面的小伙伴可能对这个再熟悉不过了,简单点讲,DOS就是服务型响应不过来,从而拒绝了正常的服务请求。
今天本文不是要讲怎么发起一个DOS攻击,而是讲一下怎么在java的代码层面尽量减少DOS的可能性。
为什么会有DOS
为什么会有DOS呢?排除恶意攻击的情况下,DOS的原因就是资源的使用不当。一般意义上我们所说的资源有CPU周期,内存,磁盘空间,和文件描述符等。
如果这些资源受到了恶意使用,那么很有可能会影响正常的系统服务响应,从而产生DOS。
怎么在编码层面上,解决DOS问题呢?
不合理的资源使用
如果系统有不合理的资源使用的话,就会造成资源紧缺,从而会产生问题。我们这里举一些不合理使用资源的例子。
请求用于矢量图的SVG文件和字体文件
SVG (全称是 Scalable Vector Graphics) 是一个跟分辨率无关的图形格式。因为SVG是基于XML的,并且保存着大量的复杂路径信息,所以它的体积一般比较大。我们在使用的时候要考虑。
同时如果使用大量的字体文件也会加重系统的资源负担。
字符串或二进制表示的图片转换
图片是一个文件,文件就可以使用二进制来表示,同样的如果我们把二进制进行base64编码就得到了图片的字符串表示。
如果使用过webpack进行前端项目构建的同学应该知道,对于项目中的小图像,一般是将其编码成为字符串直接嵌套在html中的。但是对于大图片,还是保存的原来的格式。
如果我们在后台对字符串或者二进制表示的图片进行转换的时候,可能会需要几倍于原image大小的内存。
看一个imageToBase64的例子:
public String imageToBase64() {
File f = new File("/tmp/abc.jpg");
try {
BufferedImage bi = ImageIO.read(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "jpg", baos);
byte[] bytes = baos.toByteArray();
return encoder.encodeBuffer(bytes).trim();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
zip炸弹
为了提升数据传输的效率,很多时候我们都会使用压缩算法,比如在HTTP中。但是一个压缩过的很小的zip文件,解压之后可能会变得非常非常大。
这里给大家介绍一个非常有名的zip炸弹。
42.zip 是很有名的zip炸弹。它的大小只有42KB,但是解压之后居然有4.5PB之多。
怎么做的呢?
一个zip文件中又包含了16个zip文件,每一个zip文件又包含了16个zip文件,这样循环5次,产生了16的5次方个文件,每个文件的大小是4.3GB,最后导致你的硬盘爆炸了。
感兴趣的朋友可以从http://www.unforgettable.dk/42.zip 下载,自己尝试一下。
怎么避免zip炸弹呢?
第一种做法在解压过程中检测解压过后的文件大小,如果超出一定的限制就结束解压。