如何防止Qt中的减压炸弹袭击

时间:2015-11-19 21:01:12

标签: qt security

我正在Qt。

中创建一个客户端服务器应用程序

我使用自己的算法对一些结构进行序列化和反序列化,但是为了反序列化它们,我需要将包含该对象的QByteArray加载到内存中。为了防止某种导致服务器进入OOM的黑客攻击,我设置了一个固定的限制,最大数量的数组不应该,在正常情况下,不会超过,所以如果一些“黑客”试图发送例如包含200GB数据的数组,服务器拒绝它,而不是读取数据直到它死OOM。

现在的问题是我对网络协议实施了压缩以加快速度。所以我真的不知道未压缩数据的大小,直到我在从客户端收到的字节数组上运行qUncompress。我不确定它是否在技术上可行,但我认为理论上有人可以制作易于压缩的数据,即使压缩版本的kb很少,未压缩的版本也可能有千兆字节。

有可能吗?如果是这样,有什么办法可以阻止这种情况吗?例如,以某种特定尺寸不允许膨胀的方式运行qUncompress

2 个答案:

答案 0 :(得分:0)

使用qUncompress无法做到这一点,因为它是一个非常简单的API。但是,Qt有一个很好的库,名为Quazip。它使您可以完全控制压缩,并允许您例如一旦减压达到极限就中止。

答案 1 :(得分:0)

qUncompress可分配的最大内存为2147483632字节。它略高于2GB。如果未压缩数据的大小超出此限制,qUncompress将返回空QByteArray

放气方法的压缩系数的理论极限是1032:1。可以将Gygabyte的零压缩为1兆字节。将千兆位压缩到几kb是不可能的。

如果您需要更多控制内存分配,请直接使用zlib

.pro file
LIBS += -lz
------------
#include "zlib.h"
...
QByteArray compressed = qCompress("Hello, World!");
//a four byte header contain the expected length (in bytes) of the uncompressed data
unsigned long len = (compressed[0] << 24) | (compressed[1] << 16) | (compressed[2] <<  8) | (compressed[3]);
unsigned char *buffer = new unsigned char[len + 1];

int result = ::uncompress(buffer, &len, (const unsigned char*)compressed.constData() + 4, compressed.length() - 4);

QByteArray uncompressed;
if (result == Z_OK)
    uncompressed = QByteArray((char*)buffer, len);

delete[] buffer;

qDebug() <<  uncompressed;