VYPR
High severityNVD Advisory· Published Feb 7, 2023· Updated Mar 25, 2025

[RANCHER] OS command injection in Rancher and Fleet

CVE-2022-31249

Description

CVE-2022-31249 is an OS command injection vulnerability in SUSE Rancher's Wrangler library that allows remote attackers to execute arbitrary commands on the underlying host.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CVE-2022-31249 is an OS command injection vulnerability in SUSE Rancher's Wrangler library that allows remote attackers to execute arbitrary commands on the underlying host.

CVE-2022-31249 describes an Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') vulnerability in the wrangler component of SUSE Rancher. Wrangler is a framework used to implement Kubernetes controllers, and this flaw stems from insufficient sanitization of user-supplied input when constructing operating system commands [1][2].

Exploitation occurs when an attacker provides crafted commands to Wrangler, which are then executed without proper validation. An attacker does not need prior authentication to the wrangler service, making this a remotely exploitable issue if the affected component is network-accessible [2]. The vulnerable versions include wrangler 0.7.3 and prior, 0.8.4 and prior, and 1.0.0 and prior [2].

A successful attack enables remote code execution on the host system where Wrangler is running. This could allow an attacker to escalate privileges, pivot to other systems, or compromise the entire Kubernetes cluster's infrastructure [2].

Patches have been released by the vendor. Security-fix releases are identified as v0.7.4-security1 and v0.8.5-security1 [3][4]. Users should upgrade to these patched versions or later. For Rancher deployments using Wrangler, applying the appropriate update in line with the supported Rancher version (e.g., 2.6.x or 2.7.x) is recommended [1].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/rancher/wranglerGo
< 0.7.4-security10.7.4-security1
github.com/rancher/wranglerGo
>= 0.8.0, < 0.8.5-security10.8.5-security1
github.com/rancher/wranglerGo
>= 1.0.0, < 1.0.11.0.1
github.com/rancher/wranglerGo
>= 0.8.6, < 0.8.110.8.11

Affected products

2

Patches

4
341018c8fef3

Fix up git package

https://github.com/rancher/wranglerMario MannoJan 23, 2023via ghsa
1 file changed · +6 6
  • pkg/git/git.go+6 6 modified
    @@ -68,7 +68,7 @@ func (g *Git) LsRemote(branch string, commit string) (string, error) {
     	}
     
     	output := &bytes.Buffer{}
    -	if err := g.gitCmd(output, "ls-remote", g.URL, formatRefForBranch(branch)); err != nil {
    +	if err := g.gitCmd(output, "ls-remote", "--", g.URL, formatRefForBranch(branch)); err != nil {
     		return "", err
     	}
     
    @@ -97,9 +97,9 @@ func (g *Git) Head(branch string) (string, error) {
     // Clone runs git clone with depth 1
     func (g *Git) Clone(branch string) error {
     	if branch == "" {
    -		return g.git("clone", "--depth=1", "-n", g.URL, g.Directory)
    +		return g.git("clone", "--depth=1", "-n", "--", g.URL, g.Directory)
     	}
    -	return g.git("clone", "--depth=1", "-n", "--branch", branch, g.URL, g.Directory)
    +	return g.git("clone", "--depth=1", "-n", "--branch="+branch, "--", g.URL, g.Directory)
     }
     
     // Update updates git repo if remote sha has changed
    @@ -302,22 +302,22 @@ func (g *Git) clone(branch string) error {
     }
     
     func (g *Git) fetchAndReset(rev string) error {
    -	if err := g.git("-C", g.Directory, "fetch", "origin", rev); err != nil {
    +	if err := g.git("-C", g.Directory, "fetch", "origin", "--", rev); err != nil {
     		return err
     	}
     	return g.reset("FETCH_HEAD")
     }
     
     func (g *Git) reset(rev string) error {
    -	return g.git("-C", g.Directory, "reset", "--hard", rev)
    +	return g.git("-C", g.Directory, "reset", "--hard", "--", rev)
     }
     
     func (g *Git) currentCommit() (string, error) {
     	return g.gitOutput("-C", g.Directory, "rev-parse", "HEAD")
     }
     
     func (g *Git) gitCmd(output io.Writer, args ...string) error {
    -	kv := fmt.Sprintf("credential.helper=%s", "/bin/sh -c 'echo password=$GIT_PASSWORD'")
    +	kv := fmt.Sprintf("credential.helper=%s", `/bin/sh -c 'echo "password=$GIT_PASSWORD"'`)
     	cmd := exec.Command("git", append([]string{"-c", kv}, args...)...)
     	cmd.Env = append(os.Environ(), fmt.Sprintf("GIT_PASSWORD=%s", g.password))
     	stderrBuf := &bytes.Buffer{}
    
5a387e13e8d5

Fix up git package

https://github.com/rancher/wranglerMario MannoJan 23, 2023via ghsa
1 file changed · +6 6
  • pkg/git/git.go+6 6 modified
    @@ -68,7 +68,7 @@ func (g *Git) LsRemote(branch string, commit string) (string, error) {
     	}
     
     	output := &bytes.Buffer{}
    -	if err := g.gitCmd(output, "ls-remote", g.URL, formatRefForBranch(branch)); err != nil {
    +	if err := g.gitCmd(output, "ls-remote", "--", g.URL, formatRefForBranch(branch)); err != nil {
     		return "", err
     	}
     
    @@ -97,9 +97,9 @@ func (g *Git) Head(branch string) (string, error) {
     // Clone runs git clone with depth 1
     func (g *Git) Clone(branch string) error {
     	if branch == "" {
    -		return g.git("clone", "--depth=1", "-n", g.URL, g.Directory)
    +		return g.git("clone", "--depth=1", "-n", "--", g.URL, g.Directory)
     	}
    -	return g.git("clone", "--depth=1", "-n", "--branch", branch, g.URL, g.Directory)
    +	return g.git("clone", "--depth=1", "-n", "--branch="+branch, "--", g.URL, g.Directory)
     }
     
     // Update updates git repo if remote sha has changed
    @@ -302,22 +302,22 @@ func (g *Git) clone(branch string) error {
     }
     
     func (g *Git) fetchAndReset(rev string) error {
    -	if err := g.git("-C", g.Directory, "fetch", "origin", rev); err != nil {
    +	if err := g.git("-C", g.Directory, "fetch", "origin", "--", rev); err != nil {
     		return err
     	}
     	return g.reset("FETCH_HEAD")
     }
     
     func (g *Git) reset(rev string) error {
    -	return g.git("-C", g.Directory, "reset", "--hard", rev)
    +	return g.git("-C", g.Directory, "reset", "--hard", "--", rev)
     }
     
     func (g *Git) currentCommit() (string, error) {
     	return g.gitOutput("-C", g.Directory, "rev-parse", "HEAD")
     }
     
     func (g *Git) gitCmd(output io.Writer, args ...string) error {
    -	kv := fmt.Sprintf("credential.helper=%s", "/bin/sh -c 'echo password=$GIT_PASSWORD'")
    +	kv := fmt.Sprintf("credential.helper=%s", `/bin/sh -c 'echo "password=$GIT_PASSWORD"'`)
     	cmd := exec.Command("git", append([]string{"-c", kv}, args...)...)
     	cmd.Env = append(os.Environ(), fmt.Sprintf("GIT_PASSWORD=%s", g.password))
     	stderrBuf := &bytes.Buffer{}
    
12397eec5015

Fix up git package

https://github.com/rancher/wranglerMario MannoJan 23, 2023via ghsa
1 file changed · +8 5
  • pkg/git/git.go+8 5 modified
    @@ -68,7 +68,7 @@ func (g *Git) LsRemote(branch string, commit string) (string, error) {
     	}
     
     	output := &bytes.Buffer{}
    -	if err := g.gitCmd(output, "ls-remote", g.URL, formatRefForBranch(branch)); err != nil {
    +	if err := g.gitCmd(output, "ls-remote", "--", g.URL, formatRefForBranch(branch)); err != nil {
     		return "", err
     	}
     
    @@ -96,7 +96,10 @@ func (g *Git) Head(branch string) (string, error) {
     
     // Clone runs git clone with depth 1
     func (g *Git) Clone(branch string) error {
    -	return g.git("clone", "--depth=1", "-n", "--branch", branch, g.URL, g.Directory)
    +	if branch == "" {
    +		return g.git("clone", "--depth=1", "-n", "--", g.URL, g.Directory)
    +	}
    +	return g.git("clone", "--depth=1", "-n", "--branch="+branch, "--", g.URL, g.Directory)
     }
     
     // Update updates git repo if remote sha has changed
    @@ -299,22 +302,22 @@ func (g *Git) clone(branch string) error {
     }
     
     func (g *Git) fetchAndReset(rev string) error {
    -	if err := g.git("-C", g.Directory, "fetch", "origin", rev); err != nil {
    +	if err := g.git("-C", g.Directory, "fetch", "origin", "--", rev); err != nil {
     		return err
     	}
     	return g.reset("FETCH_HEAD")
     }
     
     func (g *Git) reset(rev string) error {
    -	return g.git("-C", g.Directory, "reset", "--hard", rev)
    +	return g.git("-C", g.Directory, "reset", "--hard", "--", rev)
     }
     
     func (g *Git) currentCommit() (string, error) {
     	return g.gitOutput("-C", g.Directory, "rev-parse", "HEAD")
     }
     
     func (g *Git) gitCmd(output io.Writer, args ...string) error {
    -	kv := fmt.Sprintf("credential.helper=%s", "/bin/sh -c 'echo password=$GIT_PASSWORD'")
    +	kv := fmt.Sprintf("credential.helper=%s", `/bin/sh -c 'echo "password=$GIT_PASSWORD"'`)
     	cmd := exec.Command("git", append([]string{"-c", kv}, args...)...)
     	cmd.Env = append(os.Environ(), fmt.Sprintf("GIT_PASSWORD=%s", g.password))
     	stderrBuf := &bytes.Buffer{}
    
8649ecc06220

Fix up git package

https://github.com/rancher/wranglerGuilherme MacedoDec 20, 2022via ghsa
1 file changed · +6 6
  • pkg/git/git.go+6 6 modified
    @@ -68,7 +68,7 @@ func (g *Git) LsRemote(branch string, commit string) (string, error) {
     	}
     
     	output := &bytes.Buffer{}
    -	if err := g.gitCmd(output, "ls-remote", g.URL, formatRefForBranch(branch)); err != nil {
    +	if err := g.gitCmd(output, "ls-remote", "--", g.URL, formatRefForBranch(branch)); err != nil {
     		return "", err
     	}
     
    @@ -97,9 +97,9 @@ func (g *Git) Head(branch string) (string, error) {
     // Clone runs git clone with depth 1
     func (g *Git) Clone(branch string) error {
     	if branch == "" {
    -		return g.git("clone", "--depth=1", "-n", g.URL, g.Directory)
    +		return g.git("clone", "--depth=1", "-n", "--", g.URL, g.Directory)
     	}
    -	return g.git("clone", "--depth=1", "-n", "--branch", branch, g.URL, g.Directory)
    +	return g.git("clone", "--depth=1", "-n", "--branch="+branch, "--", g.URL, g.Directory)
     }
     
     // Update updates git repo if remote sha has changed
    @@ -302,22 +302,22 @@ func (g *Git) clone(branch string) error {
     }
     
     func (g *Git) fetchAndReset(rev string) error {
    -	if err := g.git("-C", g.Directory, "fetch", "origin", rev); err != nil {
    +	if err := g.git("-C", g.Directory, "fetch", "origin", "--", rev); err != nil {
     		return err
     	}
     	return g.reset("FETCH_HEAD")
     }
     
     func (g *Git) reset(rev string) error {
    -	return g.git("-C", g.Directory, "reset", "--hard", rev)
    +	return g.git("-C", g.Directory, "reset", "--hard", "--", rev)
     }
     
     func (g *Git) currentCommit() (string, error) {
     	return g.gitOutput("-C", g.Directory, "rev-parse", "HEAD")
     }
     
     func (g *Git) gitCmd(output io.Writer, args ...string) error {
    -	kv := fmt.Sprintf("credential.helper=%s", "/bin/sh -c 'echo password=$GIT_PASSWORD'")
    +	kv := fmt.Sprintf("credential.helper=%s", `/bin/sh -c 'echo "password=$GIT_PASSWORD"'`)
     	cmd := exec.Command("git", append([]string{"-c", kv}, args...)...)
     	cmd.Env = append(os.Environ(), fmt.Sprintf("GIT_PASSWORD=%s", g.password))
     	stderrBuf := &bytes.Buffer{}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

11

News mentions

0

No linked articles in our index yet.