fix: limit pod copy extraction size - #7962
Open
GrosQuildu wants to merge 2 commits into
Open
Conversation
GrosQuildu
marked this pull request as ready for review
June 26, 2026 15:20
GrosQuildu
requested review from
ash-thakur-rh,
manusa and
shawkins
as code owners
June 26, 2026 15:20
GrosQuildu
added a commit
to GrosQuildu/kubernetes-client
that referenced
this pull request
Jun 26, 2026
GrosQuildu
force-pushed
the
ptp-49-pod-copy-limits
branch
from
June 26, 2026 17:14
b2380fc to
25c7466
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
PodOperationsImpl.copy(Path)lets callers copy a file or directory from a pod to the client host. When the caller copies a directory, the client executestar -cf -in the pod, parses the pod-controlled stdout as a tar archive, and writes every readable non-directory entry to disk. The extraction loop validates the normalized entry name, but it does not reject sparse tar entries and does not enforce a per-entry or total extracted-byte limit.Commons Compress treats GNU sparse tar entries as readable entries. It expands their logical sparse holes into zero bytes as callers read the entry stream. A malicious pod can therefore send a small tar stream that makes the Fabric8 client write a much larger local file.
The existing Kubernetes client configuration does not provide a setting that prevents this issue.
ConfigandRequestConfigexpose timeouts, retry settings, watch reconnect settings, upload timeout, logging interval, and concurrency limits, but no maximum response-body, copy-file, tar-entry, or total download byte limit. ThelimitBytes(int)API only appends the Kubernetes pod logslimitBytesquery parameter; it does not apply tocopy(Path),read(), exec output, port-forwarding, raw responses, or object list materialization.Other remote-data download surfaces should be reviewed separately. In
PodOperationsImpl,copyFile,read, pod logs, exec and attach output, and port-forwarding can all move pod-controlled bytes to client memory, client disk, or caller-provided streams. OutsidePodOperationsImpl, APIs such asraw,load(URL), and normal list/get response materialization can also download or materialize large remote responses. These are additional hardening targets; this change focuses only on directory tar extraction.Exploit Scenario
An artifact collection service runs Fabric8 on a CI host and calls
after tenant jobs finish. A malicious tenant controls the pod image or compromises the pod. Instead of returning ordinary artifact files, the pod returns a GNU sparse tar entry with a small archive size and a large logical file size. The Fabric8 client accepts the entry, Commons Compress expands the sparse hole while reading, and
Files.copy(...)writes the expanded file into the CI workspace. Repeating this can exhaust workspace disk quota or stall the artifact service with little network transfer.PoC code that generates a GNU sparse tar archive and drives the
PodOperationsImpl.copy(Path)path:The vulnerable code produced the following output during validation:
After applying this change, the same PoC produced:
Threat Model
The question is: should kubernetes-client implement configurations that limit disk and/or memory consumption driven by remote components.
If the pod output and other remote outputs are fully trusted then no fix is needed, but entry in threat model is advised.
If the pod output (and possibly other remote outputs) may not be trusted, then this change is recommended, along with threat model note and documentation update. Likely this is the case, as this issue is similar to #2715 (though less severe).
Fix
The fix makes kubernetes-client reject sparse tar entries by default and enforce caller-configurable byte limits while copying tar entry data. A size check based only on tar metadata is not sufficient because sparse tar metadata can report a small archive entry size while the readable stream expands to a larger logical file. The copy loop must count bytes actually written.
This change adds two public request-configuration fields and matching system properties for the directory-copy path:
podCopyMaxFileBytes/kubernetes.pod.copy.max.file.bytespodCopyMaxTotalBytes/kubernetes.pod.copy.max.total.bytesBoth default to
-1, meaning no byte limit. The change also adds regression tests for sparse entries, per-file limits, total limits, and an allowed copy within the configured limits.Paweł Płatek from Trail of Bits in collaboration with OpenAI.