mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	Avoid nil user special-casing in unsecured endpoint
This commit is contained in:
		| @@ -13,6 +13,7 @@ go_library( | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apiserver/pkg/authentication/user", | ||||
|         "//vendor:k8s.io/apiserver/pkg/endpoints/filters", | ||||
|         "//vendor:k8s.io/apiserver/pkg/endpoints/request", | ||||
|         "//vendor:k8s.io/apiserver/pkg/server", | ||||
|   | ||||
| @@ -22,6 +22,7 @@ import ( | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
|  | ||||
| 	"k8s.io/apiserver/pkg/authentication/user" | ||||
| 	genericapifilters "k8s.io/apiserver/pkg/endpoints/filters" | ||||
| 	apirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||
| 	"k8s.io/apiserver/pkg/server" | ||||
| @@ -35,6 +36,7 @@ import ( | ||||
|  | ||||
| func BuildInsecureHandlerChain(apiHandler http.Handler, c *server.Config) http.Handler { | ||||
| 	handler := genericapifilters.WithAudit(apiHandler, c.RequestContextMapper, c.AuditWriter) | ||||
| 	handler = genericapifilters.WithAuthentication(handler, c.RequestContextMapper, insecureSuperuser{}, nil) | ||||
| 	handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true") | ||||
| 	handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper) | ||||
| 	handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc) | ||||
| @@ -111,3 +113,15 @@ func serveInsecurely(insecureServingInfo *InsecureServingInfo, insecureHandler h | ||||
| 	_, err = server.RunServer(insecureServer, insecureServingInfo.BindNetwork, stopCh) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // insecureSuperuser implements authenticator.Request to always return a superuser. | ||||
| // This is functionally equivalent to skipping authentication and authorization, | ||||
| // but allows apiserver code to stop special-casing a nil user to skip authorization checks. | ||||
| type insecureSuperuser struct{} | ||||
|  | ||||
| func (insecureSuperuser) AuthenticateRequest(req *http.Request) (user.Info, bool, error) { | ||||
| 	return &user.DefaultInfo{ | ||||
| 		Name:   "system:unsecured", | ||||
| 		Groups: []string{user.SystemPrivilegedGroup, user.AllAuthenticated}, | ||||
| 	}, true, nil | ||||
| } | ||||
|   | ||||
| @@ -29,9 +29,7 @@ import ( | ||||
| func EscalationAllowed(ctx genericapirequest.Context) bool { | ||||
| 	u, ok := genericapirequest.UserFrom(ctx) | ||||
| 	if !ok { | ||||
| 		// the only way to be without a user is to either have no authenticators by explicitly saying that's your preference | ||||
| 		// or to be connecting via the insecure port, in which case this logically doesn't apply | ||||
| 		return true | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	// system:masters is special because the API server uses it for privileged loopback connections | ||||
|   | ||||
| @@ -288,8 +288,7 @@ func getMatchingPolicies(lister extensionslisters.PodSecurityPolicyLister, user | ||||
| 	} | ||||
|  | ||||
| 	for _, constraint := range list { | ||||
| 		// if no user info exists then the API is being hit via the unsecured port. In this case authorize the request. | ||||
| 		if user == nil || authorizedForPolicy(user, namespace, constraint, authz) || authorizedForPolicy(sa, namespace, constraint, authz) { | ||||
| 		if authorizedForPolicy(user, namespace, constraint, authz) || authorizedForPolicy(sa, namespace, constraint, authz) { | ||||
| 			matchedPolicies = append(matchedPolicies, constraint) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -1612,25 +1612,34 @@ func TestGetMatchingPolicies(t *testing.T) { | ||||
| 			}, | ||||
| 			expectedPolicies: sets.NewString("policy1", "policy2", "policy4", "policy5"), | ||||
| 		}, | ||||
| 		"policies are allowed for nil user info": { | ||||
| 			user:    nil, | ||||
| 			sa:      &user.DefaultInfo{Name: "sa"}, | ||||
| 			ns:      "test", | ||||
| 			allowed: map[string]map[string]map[string]bool{}, // authorizer not consulted | ||||
| 		"policies are not allowed for nil user info": { | ||||
| 			user: nil, | ||||
| 			sa:   &user.DefaultInfo{Name: "sa"}, | ||||
| 			ns:   "test", | ||||
| 			allowed: map[string]map[string]map[string]bool{ | ||||
| 				"sa": { | ||||
| 					"test": {"policy1": true}, | ||||
| 				}, | ||||
| 				"user": { | ||||
| 					"test": {"policy2": true}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			inPolicies: []*extensions.PodSecurityPolicy{ | ||||
| 				policyWithName("policy1"), | ||||
| 				policyWithName("policy2"), | ||||
| 				policyWithName("policy3"), | ||||
| 			}, | ||||
| 			// all policies are allowed regardless of the permissions when user info is nil | ||||
| 			// (ie. a request hitting the unsecure port) | ||||
| 			expectedPolicies: sets.NewString("policy1", "policy2", "policy3"), | ||||
| 			// only the policies for the sa are allowed when user info is nil | ||||
| 			expectedPolicies: sets.NewString("policy1"), | ||||
| 		}, | ||||
| 		"policies are not allowed for nil sa info": { | ||||
| 			user: &user.DefaultInfo{Name: "user"}, | ||||
| 			sa:   nil, | ||||
| 			ns:   "test", | ||||
| 			allowed: map[string]map[string]map[string]bool{ | ||||
| 				"sa": { | ||||
| 					"test": {"policy1": true}, | ||||
| 				}, | ||||
| 				"user": { | ||||
| 					"test": {"policy2": true}, | ||||
| 				}, | ||||
| @@ -1643,6 +1652,26 @@ func TestGetMatchingPolicies(t *testing.T) { | ||||
| 			// only the policies for the user are allowed when sa info is nil | ||||
| 			expectedPolicies: sets.NewString("policy2"), | ||||
| 		}, | ||||
| 		"policies are not allowed for nil sa and user info": { | ||||
| 			user: nil, | ||||
| 			sa:   nil, | ||||
| 			ns:   "test", | ||||
| 			allowed: map[string]map[string]map[string]bool{ | ||||
| 				"sa": { | ||||
| 					"test": {"policy1": true}, | ||||
| 				}, | ||||
| 				"user": { | ||||
| 					"test": {"policy2": true}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			inPolicies: []*extensions.PodSecurityPolicy{ | ||||
| 				policyWithName("policy1"), | ||||
| 				policyWithName("policy2"), | ||||
| 				policyWithName("policy3"), | ||||
| 			}, | ||||
| 			// no policies are allowed if sa and user are both nil | ||||
| 			expectedPolicies: sets.NewString(), | ||||
| 		}, | ||||
| 	} | ||||
| 	for k, v := range tests { | ||||
| 		informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jordan Liggitt
					Jordan Liggitt