CVE-2022-23652 (published 2022-02-22T20:15Z)

capsule-proxy is a reverse proxy for Capsule Operator which provides multi-tenancy in Kubernetes. In versions prior to 0.2.1 an attacker with a proper authentication mechanism may use a malicious `Connection` header to start a privilege escalation attack towards the Kubernetes API Server. This vulnerability allows for an exploit of the `cluster-admin` Role bound to `capsule-proxy`. There are no known workarounds for this issue.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-287
cwe_name: Improper Authentication
description: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
extended_description: 
            
			
         
         

Fix information:
repo_url: https://github.com/clastix/capsule-proxy
commit_details: repo_url: https://github.com/clastix/capsule-proxy
author: Dario Tranchitella
author_date: 2022-02-18 20:53:34+01:00
msg: bug: cve exploiting malicious connection header
repository: repo_url: https://github.com/clastix/capsule-proxy
repo_name: projectcapsule/capsule-proxy
description: Reverse proxy for Capsule Operator.
repo_language: Go
owner: clastix
file_changes: filename: go.mod
change_type: ModificationType.MODIFY
diff: @@ -11,6 +11,7 @@ require (
 	github.com/pkg/errors v0.9.1
 	github.com/spf13/pflag v1.0.5
 	go.uber.org/zap v1.18.1
+	golang.org/x/net v0.0.0-20210520170846-37e1c6afe023
 	k8s.io/api v0.22.0
 	k8s.io/apimachinery v0.22.1
 	k8s.io/apiserver v0.22.0

programming_language: Go
filename: webserver.go
change_type: ModificationType.MODIFY
diff: @@ -10,6 +10,7 @@ import (
 	"fmt"
 	"net/http"
 	"net/http/httputil"
+	"net/textproto"
 	"strings"
 	"time"
 
@@ -18,6 +19,7 @@ import (
 	"github.com/gorilla/handlers"
 	"github.com/gorilla/mux"
 	"github.com/pkg/errors"
+	"golang.org/x/net/http/httpguts"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/apiserver/pkg/authentication/serviceaccount"
@@ -178,6 +180,9 @@ func (n kubeFilter) impersonateHandler(writer http.ResponseWriter, request *http
 	if len(n.bearerToken) > 0 {
 		request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", n.bearerToken))
 	}
+	// Dropping malicious header connection
+	// https://github.com/clastix/capsule-proxy/issues/188
+	n.removingHopByHopHeaders(request)
 
 	request.Header.Add("Impersonate-User", username)
 
@@ -355,3 +360,28 @@ func (n kubeFilter) getProxyTenantsForOwnerKind(ownerKind capsulev1beta1.OwnerKi
 
 	return
 }
+
+func (n *kubeFilter) removingHopByHopHeaders(request *http.Request) {
+	connectionHeaderName, upgradeHeaderName, requestUpgradeType := "connection", "upgrade", ""
+
+	if httpguts.HeaderValuesContainsToken(request.Header[connectionHeaderName], upgradeHeaderName) {
+		requestUpgradeType = request.Header.Get(upgradeHeaderName)
+	}
+	// Removing connection headers
+	for _, f := range request.Header.Values(connectionHeaderName) {
+		for _, sf := range strings.Split(f, ",") {
+			if sf = textproto.TrimString(sf); sf != "" {
+				request.Header.Del(sf)
+			}
+		}
+	}
+
+	if requestUpgradeType != "" {
+		request.Header.Set(connectionHeaderName, upgradeHeaderName)
+		request.Header.Set(upgradeHeaderName, requestUpgradeType)
+
+		return
+	}
+
+	request.Header.Del(connectionHeaderName)
+}

programming_language: Go