pranavshuklaa opened a new pull request, #1091:
URL: https://github.com/apache/flink-agents/pull/1091

   <!--
   * Thank you very much for contributing to Flink Agents.
   * Please add the relevant components in the PR title. E.g., [api], 
[runtime], [java], [python], [hotfix], etc.
   -->
   
   <!-- Please link the PR to the relevant issue(s). Hotfix doesn't need this. 
-->
   Linked issue: #1072
   
   ### Note on branch base
   
   This branch is built on top of #1005 (commit 5eb91e73), which is still open.
   Until #1005 merges, this PR's diff will include #1005's commits in addition
   to mine. My changes are isolated to the most recent commit on this branch 
   SkillMaterializer.java and its tests. I'll rebase onto main once #1005 lands,
   at which point the diff will show only these changes. 
   
   ### Purpose of change
   
   This change adds resource bounds for skill archives materialized from URL
   sources.
   
   A skill archive downloaded from a remote URL can otherwise consume an
   unbounded amount of disk space during download and ZIP extraction, a
   malicious or compromised source could exhaust disk space via an oversized
   download or a zip bomb. This PR adds explicit limits around both stages and
   ensures the limits are enforced using the actual data being processed, not
   just metadata the source controls.
   
   The proposed limits are:
   * **512 MiB** maximum downloaded archive size
   * **200 MiB** maximum size of a single extracted entry
   * **1 GiB** maximum total extracted size
   * **10,000** maximum number of extracted entries
   
   These values are proposed for discussion, we can adjust based on sense of 
realistic skill archive sizes.
   
   #### Download protection
   
   The download path now:
   
   * Checks the declared `Content-Length` when available and rejects archives
     already declared larger than the download limit, before reading any body
     bytes.
   * Independently tracks the number of bytes actually read from the response
     stream and rejects the download before writing bytes that would cross the
     limit.
   * Treats the streamed byte count as authoritative, so the protection holds
     even when `Content-Length` is missing, zero, or understated by the server.
   * Deletes the temporary file immediately if the download fails or is
     rejected, rather than relying solely on the JVM shutdown hook.
   
   This closes the gap where a server could bypass a `Content-Length`-only
   check simply by omitting or lying about the header, declared size is only
   ever used as a cheap early exit, never as the actual enforcement.
   
   #### ZIP extraction protection
   
   The extraction path applies layered validation:
   
   * Rejects archives with more than the configured maximum number of entries,
     before any bytes are extracted.
   * Checks declared per-entry and cumulative uncompressed sizes from the ZIP
     central directory as an early, cheap rejection where that metadata is
     present.
   * Independently tracks actual decompressed bytes written per entry and
     cumulatively across the archive, rejecting extraction before writing bytes
     that would cross either limit.
   * Preserves the existing zip-slip (path traversal) validation, run before
     any extraction begins.
   * Deletes the extraction directory immediately on any failure, in addition
     to the existing JVM shutdown hook fallback.
   
   As with the download path, declared ZIP metadata is attacker-controlled and
   is only used as an early exit ,the actual decompressed byte count during
   extraction is the real enforcement. This is deliberate: a crafted archive
   can declare an entry as 1 byte while its actual DEFLATE stream expands to
   gigabytes (a zip bomb), so trusting `ZipEntry.getSize()` alone would not be
   sufficient.
   
   #### Smoke test
   
   `SkillMaterializerSmokeTest` is included alongside the unit test coverage.
   It exercises the same core scenarios as the unit tests but with verbose
   console output, useful for manually verifying the enforcement and cleanup
   behavior end-to-end against the real HTTP and ZIP code paths. Happy to
   remove it before merge as you'd rather keep only the unit tests 
   flagging it now since it's additive rather than required.
   
   ### Tests
   
   Added unit tests in `SkillMaterializerTest` covering:
   
   * Download size limit via declared `Content-Length`
   * Download size limit via actual streamed byte count, including understated
     and missing `Content-Length`
   * Download failure cleanup (temp file removed on rejection)
   * ZIP entry count limit
   * Per-entry declared size limit (metadata pre-check)
   * Per-entry actual decompressed size limit, using a fixture with forged ZIP
     metadata so the declared size passes but the actual DEFLATE stream exceeds
     the limit, proving the byte counter, not the metadata check, is doing the
     enforcement
   * Cumulative extraction size limit
   * Extraction failure cleanup (temp directory removed on rejection)
   * Zip-slip rejection cleanup (confirms cleanup covers the pre-existing path
     traversal check too, not just the new size checks)
   * Happy-path extraction unaffected by the new checks
   
   `SkillMaterializerSmokeTest` covers the same core scenarios with readable
   console output for manual verification.
   
   Verified locally:
   
   * `SkillMaterializerTest` — all tests passing
   * `SkillMaterializerSmokeTest` — all tests passing
   
   ### API
   
   No
   
   ### Documentation
   
   <!-- Do not remove this section. Check the proper box only. -->
   
   - [ ] `doc-needed` <!-- Your PR changes impact docs -->
   - [x] `doc-not-needed` <!-- Your PR changes do not impact docs -->
   - [ ] `doc-included` <!-- Your PR already contains the necessary 
documentation updates -->
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   <!-- Do not remove this section. Check the proper box only. -->
   
   - [x] Yes
   - [ ] No
   
   `Generated-by: Generated-by: ChatGPT (GPT-5.6 Luna)` 
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to