summaryrefslogtreecommitdiffstats
path: root/recipes-containers/kubernetes/kubernetes/CVE-2020-8559.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-containers/kubernetes/kubernetes/CVE-2020-8559.patch')
-rw-r--r--recipes-containers/kubernetes/kubernetes/CVE-2020-8559.patch148
1 files changed, 148 insertions, 0 deletions
diff --git a/recipes-containers/kubernetes/kubernetes/CVE-2020-8559.patch b/recipes-containers/kubernetes/kubernetes/CVE-2020-8559.patch
new file mode 100644
index 00000000..f47826df
--- /dev/null
+++ b/recipes-containers/kubernetes/kubernetes/CVE-2020-8559.patch
@@ -0,0 +1,148 @@
1From ba3ca4929ed3887c95f94fcf97610f3449446804 Mon Sep 17 00:00:00 2001
2From: Tim Allclair <tallclair@google.com>
3Date: Wed, 17 Jun 2020 11:09:02 -0700
4Subject: [PATCH] Don't return proxied redirects to the client
5
6CVE: CVE-2020-8559
7Upstream-Status: Backport [https://github.com/kubernetes/kubernetes.git branch:release-1.16]
8Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com>
9---
10 .../k8s.io/apimachinery/pkg/util/net/http.go | 2 +-
11 .../apimachinery/pkg/util/net/http_test.go | 12 ++---
12 .../pkg/util/proxy/upgradeaware.go | 10 ++++
13 .../pkg/util/proxy/upgradeaware_test.go | 47 ++++++++++++++++++-
14 4 files changed, 62 insertions(+), 9 deletions(-)
15
16diff --git a/src/import/staging/src/k8s.io/apimachinery/pkg/util/net/http.go b/src/import/staging/src/k8s.io/apimachinery/pkg/util/net/http.go
17index bd79d6c4a09..c24fbc6921c 100644
18--- a/src/import/staging/src/k8s.io/apimachinery/pkg/util/net/http.go
19+++ b/src/import/staging/src/k8s.io/apimachinery/pkg/util/net/http.go
20@@ -431,7 +431,7 @@ redirectLoop:
21
22 // Only follow redirects to the same host. Otherwise, propagate the redirect response back.
23 if requireSameHostRedirects && location.Hostname() != originalLocation.Hostname() {
24- break redirectLoop
25+ return nil, nil, fmt.Errorf("hostname mismatch: expected %s, found %s", originalLocation.Hostname(), location.Hostname())
26 }
27
28 // Reset the connection.
29diff --git a/src/import/staging/src/k8s.io/apimachinery/pkg/util/net/http_test.go b/src/import/staging/src/k8s.io/apimachinery/pkg/util/net/http_test.go
30index 4e4e317b9a4..142b80f1a84 100644
31--- a/src/import/staging/src/k8s.io/apimachinery/pkg/util/net/http_test.go
32+++ b/src/import/staging/src/k8s.io/apimachinery/pkg/util/net/http_test.go
33@@ -330,13 +330,13 @@ func TestConnectWithRedirects(t *testing.T) {
34 redirects: []string{"/1", "/2", "/3", "/4", "/5", "/6", "/7", "/8", "/9", "/10"},
35 expectError: true,
36 }, {
37- desc: "redirect to different host are prevented",
38- redirects: []string{"http://example.com/foo"},
39- expectedRedirects: 0,
40+ desc: "redirect to different host are prevented",
41+ redirects: []string{"http://example.com/foo"},
42+ expectError: true,
43 }, {
44- desc: "multiple redirect to different host forbidden",
45- redirects: []string{"/1", "/2", "/3", "http://example.com/foo"},
46- expectedRedirects: 3,
47+ desc: "multiple redirect to different host forbidden",
48+ redirects: []string{"/1", "/2", "/3", "http://example.com/foo"},
49+ expectError: true,
50 }, {
51 desc: "redirect to different port is allowed",
52 redirects: []string{"http://HOST/foo"},
53diff --git a/src/import/staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go b/src/import/staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go
54index fcdc76a0529..3a02919d135 100644
55--- a/src/import/staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go
56+++ b/src/import/staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware.go
57@@ -298,6 +298,16 @@ func (h *UpgradeAwareHandler) tryUpgrade(w http.ResponseWriter, req *http.Reques
58 rawResponse = headerBytes
59 }
60
61+ // If the backend did not upgrade the request, return an error to the client. If the response was
62+ // an error, the error is forwarded directly after the connection is hijacked. Otherwise, just
63+ // return a generic error here.
64+ if backendHTTPResponse.StatusCode != http.StatusSwitchingProtocols && backendHTTPResponse.StatusCode < 400 {
65+ err := fmt.Errorf("invalid upgrade response: status code %d", backendHTTPResponse.StatusCode)
66+ klog.Errorf("Proxy upgrade error: %v", err)
67+ h.Responder.Error(w, req, err)
68+ return true
69+ }
70+
71 // Once the connection is hijacked, the ErrorResponder will no longer work, so
72 // hijacking should be the last step in the upgrade.
73 requestHijacker, ok := w.(http.Hijacker)
74diff --git a/src/import/staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware_test.go b/src/import/staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware_test.go
75index 7d14f6534a8..236362373cd 100644
76--- a/src/import/staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware_test.go
77+++ b/src/import/staging/src/k8s.io/apimachinery/pkg/util/proxy/upgradeaware_test.go
78@@ -493,7 +493,7 @@ func (r *noErrorsAllowed) Error(w http.ResponseWriter, req *http.Request, err er
79 r.t.Error(err)
80 }
81
82-func TestProxyUpgradeErrorResponse(t *testing.T) {
83+func TestProxyUpgradeConnectionErrorResponse(t *testing.T) {
84 var (
85 responder *fakeResponder
86 expectedErr = errors.New("EXPECTED")
87@@ -541,7 +541,7 @@ func TestProxyUpgradeErrorResponse(t *testing.T) {
88
89 func TestProxyUpgradeErrorResponseTerminates(t *testing.T) {
90 for _, intercept := range []bool{true, false} {
91- for _, code := range []int{200, 400, 500} {
92+ for _, code := range []int{400, 500} {
93 t.Run(fmt.Sprintf("intercept=%v,code=%v", intercept, code), func(t *testing.T) {
94 // Set up a backend server
95 backend := http.NewServeMux()
96@@ -601,6 +601,49 @@ func TestProxyUpgradeErrorResponseTerminates(t *testing.T) {
97 }
98 }
99
100+func TestProxyUpgradeErrorResponse(t *testing.T) {
101+ for _, intercept := range []bool{true, false} {
102+ for _, code := range []int{200, 300, 302, 307} {
103+ t.Run(fmt.Sprintf("intercept=%v,code=%v", intercept, code), func(t *testing.T) {
104+ // Set up a backend server
105+ backend := http.NewServeMux()
106+ backend.Handle("/hello", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
107+ http.Redirect(w, r, "https://example.com/there", code)
108+ }))
109+ backendServer := httptest.NewServer(backend)
110+ defer backendServer.Close()
111+ backendServerURL, _ := url.Parse(backendServer.URL)
112+ backendServerURL.Path = "/hello"
113+
114+ // Set up a proxy pointing to a specific path on the backend
115+ proxyHandler := NewUpgradeAwareHandler(backendServerURL, nil, false, false, &fakeResponder{t: t})
116+ proxyHandler.InterceptRedirects = intercept
117+ proxyHandler.RequireSameHostRedirects = true
118+ proxy := httptest.NewServer(proxyHandler)
119+ defer proxy.Close()
120+ proxyURL, _ := url.Parse(proxy.URL)
121+
122+ conn, err := net.Dial("tcp", proxyURL.Host)
123+ require.NoError(t, err)
124+ bufferedReader := bufio.NewReader(conn)
125+
126+ // Send upgrade request resulting in a non-101 response from the backend
127+ req, _ := http.NewRequest("GET", "/", nil)
128+ req.Header.Set(httpstream.HeaderConnection, httpstream.HeaderUpgrade)
129+ require.NoError(t, req.Write(conn))
130+ // Verify we get the correct response and full message body content
131+ resp, err := http.ReadResponse(bufferedReader, nil)
132+ require.NoError(t, err)
133+ assert.Equal(t, fakeStatusCode, resp.StatusCode)
134+ resp.Body.Close()
135+
136+ // clean up
137+ conn.Close()
138+ })
139+ }
140+ }
141+}
142+
143 func TestDefaultProxyTransport(t *testing.T) {
144 tests := []struct {
145 name,
146--
1472.17.0
148