Description
ZipUtil.unzip() reads every archive entry into an unbounded ByteArrayOutputStream with no limit on decompressed size, entry count, or individual entry size. The config import endpoint (POST /configs/import) passes uploaded bytes directly to this function. A zip bomb (small compressed file expanding to gigabytes) can exhaust JVM heap and crash the Admin process.
Affected Files:
shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/ZipUtil.java
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ConfigsServiceImpl.java
Proposed Change:
Add three guards in ZipUtil.unzip():
javaprivate static final long MAX_ENTRY_SIZE = 100L * 1024 * 1024; // 100 MB per entry
private static final long MAX_TOTAL_SIZE = 200L * 1024 * 1024; // 200 MB total
private static final int MAX_ENTRY_COUNT = 1000;
Throw IllegalArgumentException if any limit is exceeded during decompression.
Acceptance Criteria:
Uploading a zip bomb to /configs/import results in a 400 Bad Request response, not an OOM crash.
Legitimate config export/import files (bounded by actual plugin/selector/rule counts) are unaffected.
Limits are configurable via application.yml if needed.
Task List
No response
Description
ZipUtil.unzip() reads every archive entry into an unbounded ByteArrayOutputStream with no limit on decompressed size, entry count, or individual entry size. The config import endpoint (POST /configs/import) passes uploaded bytes directly to this function. A zip bomb (small compressed file expanding to gigabytes) can exhaust JVM heap and crash the Admin process.
Affected Files:
shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/ZipUtil.java
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ConfigsServiceImpl.java
Proposed Change:
Add three guards in ZipUtil.unzip():
javaprivate static final long MAX_ENTRY_SIZE = 100L * 1024 * 1024; // 100 MB per entry
private static final long MAX_TOTAL_SIZE = 200L * 1024 * 1024; // 200 MB total
private static final int MAX_ENTRY_COUNT = 1000;
Throw IllegalArgumentException if any limit is exceeded during decompression.
Acceptance Criteria:
Uploading a zip bomb to /configs/import results in a 400 Bad Request response, not an OOM crash.
Legitimate config export/import files (bounded by actual plugin/selector/rule counts) are unaffected.
Limits are configurable via application.yml if needed.
Task List
No response