Skip to content

Commit

Permalink
UPSTREAM: 77874: fix CVE-2019-11244: `kubectl --http-cache=<world-acc…
Browse files Browse the repository at this point in the history
…essible dir>` creates world-writeable cached schema files
  • Loading branch information
yuchengwu authored and soltysh committed Oct 10, 2019
1 parent 1eb36a4 commit 6785dbf
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package disk
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"time"

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package disk

import (
"net/http"
"os"
"path/filepath"

"github.com/gregjones/httpcache"
Expand All @@ -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"),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}

0 comments on commit 6785dbf

Please sign in to comment.