Moderate severityNVD Advisory· Published Apr 22, 2019· Updated Aug 4, 2024
kubectl creates world-writeable cached schema files
CVE-2019-11244
Description
In Kubernetes v1.8.x-v1.14.x, schema info is cached by kubectl in the location specified by --cache-dir (defaulting to $HOME/.kube/http-cache), written with world-writeable permissions (rw-rw-rw-). If --cache-dir is specified and pointed at a different location accessible to other users/groups, the written files may be modified by other users/groups and disrupt the kubectl invocation.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
k8s.io/client-goGo | >= 1.8.0, < 1.12.9 | 1.12.9 |
Affected products
1- Range: v1.8.0
Patches
1790a4f636321fix CVE-2019-11244: `kubectl --http-cache=<world-accessible dir>` creates world-writeable cached schema files
4 files changed · +84 −2
discovery/cached/disk/cached_discovery.go+2 −2 modified@@ -172,7 +172,7 @@ func (d *CachedDiscoveryClient) getCachedFile(filename string) ([]byte, error) { } func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Object) error { - if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil { + if err := os.MkdirAll(filepath.Dir(filename), 0750); err != nil { return err } @@ -191,7 +191,7 @@ func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Obj return err } - err = os.Chmod(f.Name(), 0755) + err = os.Chmod(f.Name(), 0660) if err != nil { return err }
discovery/cached/disk/cached_discovery_test.go+27 −0 modified@@ -19,6 +19,7 @@ package disk import ( "io/ioutil" "os" + "path/filepath" "testing" "time" @@ -96,6 +97,32 @@ func TestNewCachedDiscoveryClient_TTL(t *testing.T) { assert.Equal(c.groupCalls, 2) } +func TestNewCachedDiscoveryClient_PathPerm(t *testing.T) { + assert := assert.New(t) + + d, err := ioutil.TempDir("", "") + assert.NoError(err) + os.RemoveAll(d) + defer os.RemoveAll(d) + + c := fakeDiscoveryClient{} + cdc := newCachedDiscoveryClient(&c, d, 1*time.Nanosecond) + cdc.ServerGroups() + + err = filepath.Walk(d, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + assert.Equal(os.FileMode(0750), info.Mode().Perm()) + } else { + assert.Equal(os.FileMode(0660), info.Mode().Perm()) + } + return nil + }) + assert.NoError(err) +} + type fakeDiscoveryClient struct { groupCalls int resourceCalls int
discovery/cached/disk/round_tripper.go+3 −0 modified@@ -18,6 +18,7 @@ package disk import ( "net/http" + "os" "path/filepath" "github.com/gregjones/httpcache" @@ -35,6 +36,8 @@ type cacheRoundTripper struct { // corresponding requests. func newCacheRoundTripper(cacheDir string, rt http.RoundTripper) http.RoundTripper { d := diskv.New(diskv.Options{ + PathPerm: os.FileMode(0750), + FilePerm: os.FileMode(0660), BasePath: cacheDir, TempDir: filepath.Join(cacheDir, ".diskv-temp"), })
discovery/cached/disk/round_tripper_test.go+52 −0 modified@@ -22,7 +22,10 @@ import ( "net/http" "net/url" "os" + "path/filepath" "testing" + + "github.com/stretchr/testify/assert" ) // copied from k8s.io/client-go/transport/round_trippers_test.go @@ -93,3 +96,52 @@ func TestCacheRoundTripper(t *testing.T) { t.Errorf("Invalid content read from cache %q", string(content)) } } + +func TestCacheRoundTripperPathPerm(t *testing.T) { + assert := assert.New(t) + + rt := &testRoundTripper{} + cacheDir, err := ioutil.TempDir("", "cache-rt") + os.RemoveAll(cacheDir) + defer os.RemoveAll(cacheDir) + + if err != nil { + t.Fatal(err) + } + cache := newCacheRoundTripper(cacheDir, rt) + + // First call, caches the response + req := &http.Request{ + Method: http.MethodGet, + URL: &url.URL{Host: "localhost"}, + } + rt.Response = &http.Response{ + Header: http.Header{"ETag": []string{`"123456"`}}, + Body: ioutil.NopCloser(bytes.NewReader([]byte("Content"))), + StatusCode: http.StatusOK, + } + resp, err := cache.RoundTrip(req) + if err != nil { + t.Fatal(err) + } + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Fatal(err) + } + if string(content) != "Content" { + t.Errorf(`Expected Body to be "Content", got %q`, string(content)) + } + + err = filepath.Walk(cacheDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + assert.Equal(os.FileMode(0750), info.Mode().Perm()) + } else { + assert.Equal(os.FileMode(0660), info.Mode().Perm()) + } + return nil + }) + assert.NoError(err) +}
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
12- access.redhat.com/errata/RHSA-2019:3942ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2020:0020ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2020:0074ghsavendor-advisoryx_refsource_REDHATWEB
- github.com/advisories/GHSA-2575-pghm-6qqxghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2019-11244ghsaADVISORY
- www.securityfocus.com/bid/108064ghsavdb-entryx_refsource_BIDWEB
- github.com/kubernetes/client-go/commit/790a4f63632139cf6731014d00a9a8338f1fbd7dghsaWEB
- github.com/kubernetes/kubernetes/issues/76676ghsax_refsource_MISCWEB
- github.com/kubernetes/kubernetes/pull/77874ghsaWEB
- github.com/kubernetes/kubernetes/pull/77874/commits/f228ae3364729caed59087e23c42868454bc3ff4ghsaWEB
- security.netapp.com/advisory/ntap-20190509-0002ghsaWEB
- security.netapp.com/advisory/ntap-20190509-0002/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.