Mitigate CWE-409 (zip bombs) - #587
Conversation
Bound compressed and expanded input, line length, archive structure, and rotating log processing. Preserve limit and archive integrity failures for callers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Delegate ZIP64 metadata and entry decoding to Commons Compress while retaining bounded preflight, resource accounting, and integrity checks. Keep the guarded GZIP reader for bounded optional-header parsing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
There is at least one correctness/security-affecting accounting bug in compressed-byte tracking plus a notable performance regression in plaintext tail reading that should be addressed before merge.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 1
New issues introduced by this change (3)
| Severity | Finding |
|---|---|
api/src/main/java/com/microsoft/gctoolkit/io/LimitedInputStream.java — LimitedInputStream registers the initial compressed-byte count but does not update… |
|
api/src/main/java/com/microsoft/gctoolkit/io/GCLogFileSegment.java — tail(...) now collects the last N lines by streaming the entire file. This is O(file size) I/O (and… |
|
api/src/main/java/com/microsoft/gctoolkit/io/LogFileStreams.java — openValidatedZipChannel() returns a SeekableByteChannel after ZipArchivePreflight.validate() has… |
What changed in this PR
This PR mitigates CWE-409 (zip bombs) exposure in GCToolKit’s log I/O layer by introducing explicit, finite resource limits for plaintext/GZIP/ZIP inputs and enforcing them during streaming and metadata inspection.
Changes:
- Add
LogFileReadLimits+ enforcement plumbing (expanded/compressed bytes, line length, compression ratio, archive entry/metadata limits, gzip header limits) and propagate limits throughGCLogFile,SingleGCLogFile,RotatingGCLogFile, and segment/metadata readers. - Switch ZIP handling to Apache Commons Compress with a ZIP preflight validator + per-entry validation/CRC/size checks.
- Add comprehensive unit tests that exercise limit triggers and boundary behaviors across plaintext, gzip (including multi-member), and zip (including forged metadata cases).
| File | Description |
|---|---|
| pom.xml | Adds commons-compress version + dependency for ZIP mitigations. |
| api/pom.xml | Adds module dependency on commons-compress. |
| api/src/main/java/module-info.java | Declares JPMS requirement on org.apache.commons.compress. |
| api/src/main/java/com/microsoft/gctoolkit/io/LogFileReadLimits.java | Defines configurable secure defaults and validated limit configuration. |
| api/src/main/java/com/microsoft/gctoolkit/io/LogFileReadLimitExceededException.java | Introduces a dedicated unchecked exception for limit failures during lazy stream operations. |
| api/src/main/java/com/microsoft/gctoolkit/io/LogFileReadBudget.java | Tracks expanded/compressed budgets and enforces compression ratio across reads. |
| api/src/main/java/com/microsoft/gctoolkit/io/LimitedInputStream.java | Enforces budgets while reading and tracks compressed/expanded ratios. |
| api/src/main/java/com/microsoft/gctoolkit/io/LimitedGZIPInputStream.java | Implements a bounded/validated GZIP reader with header/member limits and ratio checks. |
| api/src/main/java/com/microsoft/gctoolkit/io/BoundedLineSpliterator.java | Enforces maximum decoded characters per line with proper close-on-failure semantics. |
| api/src/main/java/com/microsoft/gctoolkit/io/ZipArchivePreflight.java | Validates ZIP central directory structure/size bounds before indexing/streaming. |
| api/src/main/java/com/microsoft/gctoolkit/io/LogFileStreams.java | Centralizes safe stream creation for plaintext/gzip/zip entries with validation and limits. |
| api/src/main/java/com/microsoft/gctoolkit/io/GCLogFile.java | Adds per-log immutable read-limits and ensures stream closures in diary() discovery. |
| api/src/main/java/com/microsoft/gctoolkit/io/SingleGCLogFile.java | Routes streaming through LogFileStreams with per-operation budgets and limit enforcement. |
| api/src/main/java/com/microsoft/gctoolkit/io/RotatingGCLogFile.java | Streams rotating segments through LogFileStreams.segment(...) with a shared budget. |
| api/src/main/java/com/microsoft/gctoolkit/io/SingleLogFileMetadata.java | Propagates read limits into segment inspection. |
| api/src/main/java/com/microsoft/gctoolkit/io/RotatingLogFileMetadata.java | Applies limits when enumerating ZIP entries and directory segments; improves ordering logic. |
| api/src/main/java/com/microsoft/gctoolkit/io/GCLogFileSegment.java | Propagates read limits into segment streaming and timestamp inspection. |
| api/src/main/java/com/microsoft/gctoolkit/io/GCLogFileZipSegment.java | Uses validated ZIP entry streaming with limits and avoids leaking ZIP file handles. |
| api/src/main/java/com/microsoft/gctoolkit/jvm/AbstractJavaVirtualMachine.java | Ensures data source streams are closed and surfaces I/O as unchecked for lazy failures. |
| api/src/main/java/com/microsoft/gctoolkit/GCToolKit.java | Preserves checked-IOException behavior by unwrapping UncheckedIOException; passes through limit exceptions. |
| api/src/main/java/com/microsoft/gctoolkit/io/DataSource.java | Documents limit-exceeded failures during terminal stream operations. |
| api/src/test/java/com/microsoft/gctoolkit/io/SingleGCLogFileReadLimitsTest.java | Adds extensive tests covering ZIP/GZIP edge cases and limit enforcement. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if (compressedBytes != null) { | ||
| budget.registerCompressedBytes(compressedBytes.getAsLong()); | ||
| } |
| private List<String> tail(int numberOfLines, LogFileReadBudget readBudget) { | ||
| try (Stream<String> lines = stream(readBudget)) { | ||
| return lines.collect(tailCollector(numberOfLines)); | ||
| } |
| try { | ||
| ZipArchivePreflight.validate(channel, path, limits); | ||
| return channel; |
0964bec to
fc7a92a
Compare
Raise the finite expanded-byte and line-length defaults above the largest existing regression fixtures while retaining independent compression and archive safeguards. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|





Mitigations for CodeQL-detected vulnerability that this library would (might) expose a consumer to.
See CWE-409 for a longer description and more context.
Alternatives to consider: