internal/concierge/impersonator: fail if impersonation headers set

If someone has already set impersonation headers in their request, then
we should fail loudly so the client knows that its existing impersonation
headers will not work.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
This commit is contained in:
Andrew Keesler 2021-02-16 08:15:50 -05:00
parent fdd8ef5835
commit c7905c6638
No known key found for this signature in database
GPG Key ID: 27CE0444346F9413
2 changed files with 48 additions and 0 deletions

View File

@ -88,6 +88,12 @@ func (p *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
"method", r.Method,
)
if err := ensureNoImpersonationHeaders(r); err != nil {
log.Error(err, "impersonation header already exists")
http.Error(w, "impersonation header already exists", http.StatusBadRequest)
return
}
tokenCredentialReq, err := extractToken(r, p.jsonDecoder)
if err != nil {
log.Error(err, "invalid token encoding")
@ -120,6 +126,24 @@ func (p *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
p.proxy.ServeHTTP(w, newR)
}
func ensureNoImpersonationHeaders(r *http.Request) error {
if _, ok := r.Header[transport.ImpersonateUserHeader]; ok {
return fmt.Errorf("%q header already exists", transport.ImpersonateUserHeader)
}
if _, ok := r.Header[transport.ImpersonateGroupHeader]; ok {
return fmt.Errorf("%q header already exists", transport.ImpersonateGroupHeader)
}
for header := range r.Header {
if strings.HasPrefix(header, transport.ImpersonateUserExtraHeaderPrefix) {
return fmt.Errorf("%q header already exists", transport.ImpersonateUserExtraHeaderPrefix)
}
}
return nil
}
func getProxyHeaders(userInfo user.Info, requestHeaders http.Header) http.Header {
newHeaders := http.Header{}
newHeaders.Set("Impersonate-User", userInfo.GetName())

View File

@ -127,6 +127,30 @@ func TestImpersonator(t *testing.T) {
},
wantCreationErr: "could not get in-cluster transport: using a custom transport with TLS certificate options or the insecure flag is not allowed",
},
{
name: "Impersonate-User header already in request",
getKubeconfig: func() (*rest.Config, error) { return &testServerKubeconfig, nil },
request: newRequest(map[string][]string{"Impersonate-User": {"some-user"}}),
wantHTTPBody: "impersonation header already exists\n",
wantHTTPStatus: http.StatusBadRequest,
wantLogs: []string{"\"error\"=\"\\\"Impersonate-User\\\" header already exists\" \"msg\"=\"impersonation header already exists\" \"method\"=\"GET\" \"url\"=\"http://pinniped.dev/blah\""},
},
{
name: "Impersonate-Group header already in request",
getKubeconfig: func() (*rest.Config, error) { return &testServerKubeconfig, nil },
request: newRequest(map[string][]string{"Impersonate-Group": {"some-group"}}),
wantHTTPBody: "impersonation header already exists\n",
wantHTTPStatus: http.StatusBadRequest,
wantLogs: []string{"\"error\"=\"\\\"Impersonate-Group\\\" header already exists\" \"msg\"=\"impersonation header already exists\" \"method\"=\"GET\" \"url\"=\"http://pinniped.dev/blah\""},
},
{
name: "Impersonate-Extra header already in request",
getKubeconfig: func() (*rest.Config, error) { return &testServerKubeconfig, nil },
request: newRequest(map[string][]string{"Impersonate-Extra-something": {"something"}}),
wantHTTPBody: "impersonation header already exists\n",
wantHTTPStatus: http.StatusBadRequest,
wantLogs: []string{"\"error\"=\"\\\"Impersonate-Extra-\\\" header already exists\" \"msg\"=\"impersonation header already exists\" \"method\"=\"GET\" \"url\"=\"http://pinniped.dev/blah\""},
},
{
name: "missing authorization header",
getKubeconfig: func() (*rest.Config, error) { return &testServerKubeconfig, nil },