From b99c4773a2df7fc8a2fed9a2e4fc72c86fddf211 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Thu, 2 Jun 2022 09:23:34 -0700 Subject: [PATCH] Use CSP headers in auth handler response When response_mode=form_post is requested, some error cases will be returned to the client using the form_post web page to POST the result back to the client's redirect URL. --- internal/oidc/auth/auth_handler.go | 10 ++++++++-- internal/oidc/auth/auth_handler_test.go | 21 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/internal/oidc/auth/auth_handler.go b/internal/oidc/auth/auth_handler.go index b4b9fccd..698ea7f3 100644 --- a/internal/oidc/auth/auth_handler.go +++ b/internal/oidc/auth/auth_handler.go @@ -24,6 +24,7 @@ import ( "go.pinniped.dev/internal/oidc/downstreamsession" "go.pinniped.dev/internal/oidc/login" "go.pinniped.dev/internal/oidc/provider" + "go.pinniped.dev/internal/oidc/provider/formposthtml" "go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/psession" "go.pinniped.dev/pkg/oidcclient/nonce" @@ -46,7 +47,7 @@ func NewHandler( upstreamStateEncoder oidc.Encoder, cookieCodec oidc.Codec, ) http.Handler { - return securityheader.Wrap(httperr.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { + handler := httperr.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { if r.Method != http.MethodPost && r.Method != http.MethodGet { // https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest // Authorization Servers MUST support the use of the HTTP GET and POST methods defined in @@ -105,7 +106,12 @@ func NewHandler( upstreamStateEncoder, cookieCodec, ) - })) + }) + + // During a response_mode=form_post auth request using the browser flow, the custom form_post html page may + // be used to post certain errors back to the CLI from this handler's response, so allow the form_post + // page's CSS and JS to run. + return securityheader.WrapWithCustomCSP(handler, formposthtml.ContentSecurityPolicy()) } func handleAuthRequestForLDAPUpstreamCLIFlow( diff --git a/internal/oidc/auth/auth_handler_test.go b/internal/oidc/auth/auth_handler_test.go index dc93c42a..11431a0b 100644 --- a/internal/oidc/auth/auth_handler_test.go +++ b/internal/oidc/auth/auth_handler_test.go @@ -521,6 +521,7 @@ func TestAuthorizationEndpoint(t *testing.T) { wantStatus int wantContentType string wantBodyString string + wantBodyRegex string wantBodyJSON string wantCSRFValueInCookieHeader string wantBodyStringWithLocationInHref bool @@ -1537,6 +1538,20 @@ func TestAuthorizationEndpoint(t *testing.T) { wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeInvalidScopeErrorQuery), wantBodyString: "", }, + { + name: "form_post page is used to send errors to client using OIDC upstream browser flow with response_mode=form_post", + idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()), + generateCSRF: happyCSRFGenerator, + generatePKCE: happyPKCEGenerator, + generateNonce: happyNonceGenerator, + stateEncoder: happyStateEncoder, + cookieEncoder: happyCookieEncoder, + method: http.MethodGet, + path: modifiedHappyGetRequestPath(map[string]string{"response_mode": "form_post", "scope": "openid profile email tuna"}), + wantStatus: http.StatusOK, + wantContentType: htmlContentType, + wantBodyRegex: `