fix(kubernetes-client-api): run kubeconfig exec args without shell - #7965
Open
GrosQuildu wants to merge 3 commits into
Open
fix(kubernetes-client-api): run kubeconfig exec args without shell#7965GrosQuildu wants to merge 3 commits into
GrosQuildu wants to merge 3 commits into
Conversation
GrosQuildu
marked this pull request as ready for review
June 26, 2026 15:28
GrosQuildu
requested review from
ash-thakur-rh,
manusa and
shawkins
as code owners
June 26, 2026 15:28
GrosQuildu
marked this pull request as draft
June 26, 2026 15:43
GrosQuildu
added a commit
to GrosQuildu/kubernetes-client
that referenced
this pull request
Jun 26, 2026
GrosQuildu
marked this pull request as ready for review
June 26, 2026 17:06
GrosQuildu
force-pushed
the
fix-kubeconfig-exec-args
branch
from
June 26, 2026 17:14
d2462ac to
5c9d891
Compare
GrosQuildu
force-pushed
the
fix-kubeconfig-exec-args
branch
from
June 26, 2026 17:17
5c9d891 to
a189a42
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
The kubernetes-client runs kubeconfig exec credential plugins through a shell. In
getAuthenticatorCommandFromExecConfig, kubernetes-client prependssh -con Unix-like systems (Utils.getCommandPlatformPrefix), concatenates the configured command and allexec.argsinto one string, and gives that string toProcessBuilder.Kubeconfig
exec.argsare supposed to be process arguments, not shell syntax. The bug is that kubernetes-client evaluates those arguments as shell source code.The custom
shellQuotemethod is used to command prevent injections:Two payload styles demonstrate the same root cause:
No literal whitespace or quotes:
kubernetes-client quote helper leaves this unchanged. The shell treats
;as a command separator and expands${IFS}to whitespace, sotouchruns as a second command.Whitespace inside command substitution:
kubernetes-client wraps this in double quotes because it contains a space, but double quotes still allow
$()command substitution. The shell runstouchbefore the credential plugin receives the argument.Exploit Scenario
A kubeconfig
users[].user.execwith a trusted command and a malicious arg like below demonstrates the issue.Threat Model
This is not a vulnerability when an attacker controls the whole kubeconfig, because kubeconfig exec plugins are executable configuration by design. The vulnerable case is a wrapper, operator, CI job, or policy system that fixes or allowlists the exec plugin command but lets a less-trusted caller influence arguments.
client-go Behavior Cross-Validation
The recommended fix matches the behavior of
client-go, which is the exec-auth implementation used bykubectl.client-gostores the kubeconfig command and args separately, then executes them with argv semantics:plugin/pkg/client/auth/exec/exec.go:cmd: filepath.Clean(config.Command)andargs: config.Argsplugin/pkg/client/auth/exec/exec.go:exec.Command(a.cmd, a.args...)The kubeconfig API also describes
exec.argsas process arguments, not shell text:tools/clientcmd/api/types.gosaysArgsare "Arguments to pass to the command when executing it." The generated Kubernetes kubeconfig reference uses the same wording forExecConfig.args.Local probes against
client-gocommitd04ac3067ff1confirmed this behavior:ignored;touch${IFS}<marker>was passed literally to the exec plugin; the marker file was not created.$CLIENT_GO_ENV_PROBEwas passed literally even when the environment containedCLIENT_GO_ENV_PROBE=expanded.This is also consistent with Go's
os/execdocumentation:os/execdoes not invoke a shell and does not perform shell-style expansions; environment expansion only happens if the caller explicitly usesos.ExpandEnv. No such expansion exists in theclient-goexec-auth path.With the proposed kubernetes-client patch, the same
ignored;touch${IFS}<marker>probe no longer creates the marker file becauseProcessBuilderreceives the credential plugin command and eachexec.argsentry as separate argv elements.Paweł Płatek from Trail of Bits in collaboration with OpenAI.