freegenタスクでエクセルを使うと「ZipBomb detected!」が発生することがある

318 views
Skip to first unread message

jet

unread,
Apr 19, 2021, 6:34:05 AM4/19/21
to DBFluteユーザの集い
お世話になっております。
jetと申します。

早速ですが、現在freegenの機能でexcelを読み込んで処理をしている箇所があるのですが、
excelのファイルサイズが450kbyte程度を超えると
poiのzip bomb検出機能が働いて、例外が発生する場合があります。

この例外はpoiの保護機能なので、
ZipSecureFile.setMinInflateRatio()で0を指定すると無効にできるようなのですが、
そういった設定をすることは可能でしょうか。

例外のスタックトレースは以下の通りです。

2021-04-19 15:58:26,644 [main] INFO  (DfDataSourceHandler#prepare():81) -   user   = freegen
2021-04-19 15:58:33,928 [main] ERROR (DfDBFluteTaskUtil#logException():150) - Look! Read the message below.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Failed to execute DBFlute Task 'df-freegen'.
[Advice]
Check the exception messages and the stack traces.
* * * * * * * * * */
java.lang.IllegalStateException: Failed to create workbook: ..\excel\client\src\app\bus\l3.xlsx
 at org.dbflute.helper.io.xls.DfXlsFactory.createXSSFWorkbook(DfXlsFactory.java:104)
 at org.dbflute.helper.io.xls.DfXlsFactory.createWorkbook(DfXlsFactory.java:82)
 at org.dbflute.logic.manage.freegen.table.xls.DfXlsTableLoader.loadTable(DfXlsTableLoader.java:103)
 at org.dbflute.logic.manage.freegen.DfFreeGenInitializer.initialize(DfFreeGenInitializer.java:94)
 at org.dbflute.task.manage.DfFreeGenTask.prepareFreeGenRequestList(DfFreeGenTask.java:99)
 at org.dbflute.task.manage.DfFreeGenTask.doExecute(DfFreeGenTask.java:89)
 at org.dbflute.task.bs.DfAbstractTexenTask$1.callActualExecute(DfAbstractTexenTask.java:129)
 at org.dbflute.task.bs.assistant.DfTaskBasicController.doExecute(DfTaskBasicController.java:192)
 at org.dbflute.task.bs.assistant.DfTaskBasicController.execute(DfTaskBasicController.java:78)
 at org.dbflute.task.bs.DfAbstractTexenTask.execute(DfAbstractTexenTask.java:151)
 at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
 at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
 at org.apache.tools.ant.Task.perform(Task.java:348)
 at org.apache.tools.ant.Target.execute(Target.java:357)
 at org.apache.tools.ant.Target.performTasks(Target.java:385)
 at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
 at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
 at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
 at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
 at org.apache.tools.ant.Main.runBuild(Main.java:698)
 at org.apache.tools.ant.Main.startAnt(Main.java:199)
 at org.apache.tools.ant.launch.Launcher.run(Launcher.java:257)
 at org.apache.tools.ant.launch.Launcher.main(Launcher.java:104)
Caused by: org.dbflute.util.DfReflectionUtil$ReflectionFailureException: The InvocationTargetException occurred: public org.apache.poi.xssf.usermodel.XSSFWorkbook(java.io.InputStream) throws java.io.IOException
 at org.dbflute.util.DfReflectionUtil.newInstance(DfReflectionUtil.java:144)
 at org.dbflute.helper.io.xls.DfXlsFactory.createXSSFWorkbook(DfXlsFactory.java:100)
 ... 25 more
Caused by: java.io.IOException: Zip bomb detected! The file would exceed the max. ratio of compressed file size to the size of the expanded data.
This may indicate that the file is used to inflate memory usage and thus could pose a security risk.
You can adjust this limit via ZipSecureFile.setMinInflateRatio() if you need to work with files which exceed this limit.
Uncompressed size: 358495, Raw/compressed size: 3584, ratio: 0.009997
Limits: MIN_INFLATE_RATIO: 0.010000, Entry: xl/styles.xml
 at org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream.checkThreshold(ZipArchiveThresholdInputStream.java:132)
 at org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream.read(ZipArchiveThresholdInputStream.java:82)
 at org.apache.poi.util.IOUtils.toByteArray(IOUtils.java:182)
 at org.apache.poi.util.IOUtils.toByteArray(IOUtils.java:149)
 at org.apache.poi.openxml4j.util.ZipArchiveFakeEntry.<init>(ZipArchiveFakeEntry.java:47)
 at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.<init>(ZipInputStreamZipEntrySource.java:53)
 at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:106)
 at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:307)
 at org.apache.poi.ooxml.util.PackageHelper.open(PackageHelper.java:47)
 at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:309)
 at sun.reflect.GeneratedConstructorAccessor30.newInstance(Unknown Source)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
 at org.dbflute.util.DfReflectionUtil.newInstance(DfReflectionUtil.java:135)
 ... 26 more



kubo

unread,
Apr 19, 2021, 6:59:20 AM4/19/21
to DBFluteユーザの集い
jfluteです

jetさん、こんばんは!


おおぉ、全然知らないエラーですね。情報ありがとうございます。

例外の発生箇所はこちら、xlsxファイルの作成箇所で落ちていると。
(XSSFのPOIには依存しないように全部リフレクションで処理してます)

そして、POIのsetMinInflateRatio()がこちら、staticの定数に打ち込んでますね。


これって、もう問答無用で 0 に設定しちゃっても大丈夫でしょうかね?
単なるリミッターであれば、デカいサイズのデータは自己管理してもらえばいいだけですし。
(xlsxを使うってことは、そもそもデカいサイズのデータを扱いたいわけですし)


リフレクションで無理やり呼び出すのに少し実装かかりますが、0固定でsetするだけならサクッとできちゃうとは思います。



jet

unread,
Apr 19, 2021, 9:23:50 PM4/19/21
to DBFluteユーザの集い
jfluteさん

お世話になります。

問答無用で0でいいと思います。

xlsxファイルは内部的にはzip圧縮されたxmlファイルなので
誰が作成したかわからないようなエクセルファイルを使用するのであれば
セキュリティ上意識する必要があるかもしれませんが、
freegenでの利用の場合は作成者は開発者ぐらいしかありえないので
特に意識する必要はないと考えています。

0固定でsetしていただけますでしょうか。

よろしくお願いいたします。

2021年4月19日月曜日 19:59:20 UTC+9 jflute:

kubo

unread,
Apr 20, 2021, 2:29:04 AM4/20/21
to DBFluteユーザの集い
jfluteです。

了解です。ありがとうございます。


リフレクションで無理やりsetするプログラムを書いてみました。

ただ申し訳ないですが、POI-OOXML を確認する環境が手元にないもので、
以下のURLから、dbflute.jar をダウンロードし試して頂けないでしょうか?


(1.2.4想定です)
DBFlute Engine の lib ディレクトリの dbflute.jar と差し替えてみてください。
mydbflute/dbflute-1.2.4/lib/dbflute.jar


workbookを作成するときに、以下のログが出てくるはずです。

_log.info("...Setting minumum inflate ratio as zero for large xlsx file");



jet

unread,
Apr 20, 2021, 9:30:34 AM4/20/21
to DBFluteユーザの集い
jfulteさん

お世話になります。

jetと申します。

早々に対応いただきありがとうございます。

早速使用し、結果をご報告いたします。


2021年4月20日火曜日 15:29:04 UTC+9 jflute:

jet

unread,
Apr 20, 2021, 10:02:26 PM4/20/21
to DBFluteユーザの集い
jfulteさん

お世話になります。

jetと申します。

想定通りに動作いたしました。
ありがとうございます。

logなど何か確認したいものがあれば取得いたしますので、
ご連絡ください。

よろしくお願いいたします。

2021年4月20日火曜日 15:29:04 UTC+9 jflute:
jfluteです。

kubo

unread,
May 3, 2021, 1:44:31 AM5/3/21
to DBFluteユーザの集い
jfluteです

jetさん、遅くなりましたが、動作確認ありがとうございます!


一応、そのままの状態で DBFlute-1.2.4 にパッチとして当てました。
サイト上の 1.2.4 でも同じように解決ができる状態のはずです。

でも、こないだお渡ししたjarを適用したそのままでも問題ありません。
(一応、DBFluteとしてはいつからされてるものなのか?のけじめを付けるためにということで^^)


それにしても、そこまで ReplaceSchema をしっかり使いこなしてくださっているのとても嬉しいです。


一方で、徐々にテストデータのメインをTSVファイルにしようとも思っています。

XLSの方が機能豊富だったのを、TSVも同じくらいにするってことで、別にXLSの機能を削るわけではないです。

ただ、gitのマージ的にテキストファイルの方が良いということで、身の回りの現場ではTSVがほとんどになってしまいました。

ExampleとかドキュメントとかもTSVの方をもうちょい推していくような感じになるかもしれません。


Reply all
Reply to author
Forward
0 new messages