ZipBombとは
こういうものらしい。
高圧縮ファイル爆弾(こうあっしゅくファイルばくだん)とは、それを読み込んだプログラムやシステムをクラッシュさせる、あるいは負荷により使用不能とするために作られた悪意のある圧縮ファイルである。
Apache POIでは圧縮率や最大サイズ(4GB)をチェックしてるらしい
ドキュメントより
https://poi.apache.org/apidocs/4.1/
Class ZipSecureFile
setMinInflateRatio
public static void setMinInflateRatio(double ratio)
Sets the ratio between de- and inflated bytes to detect zipbomb. It defaults to 1% (= 0.01d), i.e. when the compression is better than 1% for any given read package part, the parsing will fail indicating a Zip-Bomb.
setMaxEntrySize
public static void setMaxEntrySize(long maxEntrySize)
Sets the maximum file size of a single zip entry. It defaults to 4GB, i.e. the 32-bit zip format maximum. This can be used to limit memory consumption and protect against security vulnerabilities when documents are provided by users.
ということで、
- 圧縮率 1%以上はZip-Bomb
- 4GB以上はメモリを食うからダメ
これがデフォルトの設定になっているらしいです。
許容する圧縮率を上げる
// エクセルを開く前に
ZipSecureFile.setMinInflateRatio(0.001);
try(エクセルファイルを読むこむコード){
...
}
// 処理が終わったら戻しておく
ZipSecureFile.setMinInflateRatio(0.01);
これでエクセルファイルがPOIで開いて扱えるようになります。
圧縮率ってどんなもの?
ファイル・フォルダ名 | サイズ |
---|---|
適当な文字列.xlsx | 0.42MB |
適当な文字列 | 4.98MB |
適当な文字列(関数あり).xlsx | 1.08MB |
適当な文字列(関数あり) | 13.5MB |
- .xlsxで保存
- 拡張子をZipに変更
- Zipファイルを展開
この手順でファイルサイズ、フォルダサイズがどうなるか調べました。
この結果だけ見ると、0.01(1%)まで圧縮されていない感じがしますね。
仕事で扱ったものについてはまだ検証していないのでですが、今回の結果では0.08~0.06ぐらいの圧縮率のようです。
とりあえずログに
Zip bomb detected!
が出力されていれば、圧縮率の問題なので、
ZipSecureFile.setMinInflateRatio(0.01);
これをエクセルを開く前に実行すれば開けるはず!
参考にしたサイト