@@ -478,7 +478,7 @@ func (p *OAuthProxy) serveHTTP(rw http.ResponseWriter, req *http.Request) {
478478
479479 switch path := req.URL.Path; {
480480 case path == p.RobotsPath:
481− p.RobotsTxt(rw)
481+ p.RobotsTxt(rw, req)
482482 case p.IsAllowedRequest(req):
483483 p.SkipAuthProxy(rw, req)
484484 case path == p.SignInPath:
@@ -499,30 +499,49 @@ func (p *OAuthProxy) serveHTTP(rw http.ResponseWriter, req *http.Request) {
499499}
500500
501501// RobotsTxt disallows scraping pages from the OAuthProxy
502−func (p *OAuthProxy) RobotsTxt(rw http.ResponseWriter) {
502+func (p *OAuthProxy) RobotsTxt(rw http.ResponseWriter, req *http.Request) {
503503 _, err := fmt.Fprintf(rw, "User-agent: *\nDisallow: /")
504504 if err != nil {
505505 logger.Printf("Error writing robots.txt: %v", err)
506− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
506+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
507507 return
508508 }
509509 rw.WriteHeader(http.StatusOK)
510510}
511511
512512// ErrorPage writes an error response
513−func (p *OAuthProxy) ErrorPage(rw http.ResponseWriter, code int, title string, message string) {
513+func (p *OAuthProxy) ErrorPage(rw http.ResponseWriter, req *http.Request, code int, title string, message string) {
514+ redirectURL, err := p.getAppRedirect(req)
515+ if err != nil {
516+ logger.Errorf("Error obtaining redirect: %v", err)
517+ }
518+ if redirectURL == p.SignInPath || redirectURL == "" {
519+ redirectURL = "/"
520+ }
521+
514522 rw.WriteHeader(code)
523+
524+ // We allow unescaped template.HTML since it is user configured options
525+ /* #nosec G203 */
515526 t := struct {
516527 Title string
517528 Message string
518529 ProxyPrefix string
530+ StatusCode int
531+ Redirect string
532+ Footer template.HTML
533+ Version string
519534 }{
520− Title: fmt.Sprintf("%d %s", code, title),
535+ Title: title,
521536 Message: message,
522537 ProxyPrefix: p.ProxyPrefix,
538+ StatusCode: code,
539+ Redirect: redirectURL,
540+ Footer: template.HTML(p.Footer),
541+ Version: VERSION,
523542 }
524− err := p.templates.ExecuteTemplate(rw, "error.html", t)
525− if err != nil {
543+
544+ if err := p.templates.ExecuteTemplate(rw, "error.html", t); err != nil {
526545 logger.Printf("Error rendering error.html template: %v", err)
527546 http.Error(rw, "Internal Server Error", http.StatusInternalServerError)
528547 }
@@ -570,7 +589,7 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
570589 err := p.ClearSessionCookie(rw, req)
571590 if err != nil {
572591 logger.Printf("Error clearing session cookie: %v", err)
573− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
592+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
574593 return
575594 }
576595 rw.WriteHeader(code)
@@ -578,7 +597,7 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
578597 redirectURL, err := p.getAppRedirect(req)
579598 if err != nil {
580599 logger.Errorf("Error obtaining redirect: %v", err)
581− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
600+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
582601 return
583602 }
584603
@@ -611,7 +630,7 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
611630 err = p.templates.ExecuteTemplate(rw, "sign_in.html", t)
612631 if err != nil {
613632 logger.Printf("Error rendering sign_in.html template: %v", err)
614− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
633+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
615634 }
616635}
617636
@@ -639,7 +658,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) {
639658 redirect, err := p.getAppRedirect(req)
640659 if err != nil {
641660 logger.Errorf("Error obtaining redirect: %v", err)
642− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
661+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
643662 return
644663 }
645664
@@ -649,7 +668,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) {
649668 err = p.SaveSession(rw, req, session)
650669 if err != nil {
651670 logger.Printf("Error saving session: %v", err)
652− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
671+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
653672 return
654673 }
655674 http.Redirect(rw, req, redirect, http.StatusFound)
@@ -688,7 +707,7 @@ func (p *OAuthProxy) UserInfo(rw http.ResponseWriter, req *http.Request) {
688707 err = json.NewEncoder(rw).Encode(userInfo)
689708 if err != nil {
690709 logger.Printf("Error encoding user info: %v", err)
691− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
710+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
692711 }
693712}
694713
@@ -697,13 +716,13 @@ func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) {
697716 redirect, err := p.getAppRedirect(req)
698717 if err != nil {
699718 logger.Errorf("Error obtaining redirect: %v", err)
700− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
719+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
701720 return
702721 }
703722 err = p.ClearSessionCookie(rw, req)
704723 if err != nil {
705724 logger.Errorf("Error clearing session cookie: %v", err)
706− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
725+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
707726 return
708727 }
709728 http.Redirect(rw, req, redirect, http.StatusFound)
@@ -715,14 +734,14 @@ func (p *OAuthProxy) OAuthStart(rw http.ResponseWriter, req *http.Request) {
715734 nonce, err := encryption.Nonce()
716735 if err != nil {
717736 logger.Errorf("Error obtaining nonce: %v", err)
718− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
737+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
719738 return
720739 }
721740 p.SetCSRFCookie(rw, req, nonce)
722741 redirect, err := p.getAppRedirect(req)
723742 if err != nil {
724743 logger.Errorf("Error obtaining redirect: %v", err)
725− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
744+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
726745 return
727746 }
728747 redirectURI := p.getOAuthRedirectURI(req)
@@ -738,34 +757,34 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
738757 err := req.ParseForm()
739758 if err != nil {
740759 logger.Errorf("Error while parsing OAuth2 callback: %v", err)
741− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
760+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
742761 return
743762 }
744763 errorString := req.Form.Get("error")
745764 if errorString != "" {
746765 logger.Errorf("Error while parsing OAuth2 callback: %s", errorString)
747− p.ErrorPage(rw, http.StatusForbidden, "Permission Denied", errorString)
766+ p.ErrorPage(rw, req, http.StatusForbidden, "Permission Denied", errorString)
748767 return
749768 }
750769
751770 session, err := p.redeemCode(req)
752771 if err != nil {
753772 logger.Errorf("Error redeeming code during OAuth2 callback: %v", err)
754− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", "Internal Error")
773+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", "Internal Error")
755774 return
756775 }
757776
758777 err = p.enrichSessionState(req.Context(), session)
759778 if err != nil {
760779 logger.Errorf("Error creating session during OAuth2 callback: %v", err)
761− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", "Internal Error")
780+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", "Internal Error")
762781 return
763782 }
764783
765784 state := strings.SplitN(req.Form.Get("state"), ":", 2)
766785 if len(state) != 2 {
767786 logger.Error("Error while parsing OAuth2 state: invalid length")
768− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", "Invalid State")
787+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", "Invalid State")
769788 return
770789 }
771790 nonce := state[0]
@@ -773,13 +792,13 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
773792 c, err := req.Cookie(p.CSRFCookieName)
774793 if err != nil {
775794 logger.PrintAuthf(session.Email, req, logger.AuthFailure, "Invalid authentication via OAuth2: unable to obtain CSRF cookie")
776− p.ErrorPage(rw, http.StatusForbidden, "Permission Denied", err.Error())
795+ p.ErrorPage(rw, req, http.StatusForbidden, "Permission Denied", err.Error())
777796 return
778797 }
779798 p.ClearCSRFCookie(rw, req)
780799 if c.Value != nonce {
781800 logger.PrintAuthf(session.Email, req, logger.AuthFailure, "Invalid authentication via OAuth2: CSRF token mismatch, potential attack")
782− p.ErrorPage(rw, http.StatusForbidden, "Permission Denied", "CSRF Failed")
801+ p.ErrorPage(rw, req, http.StatusForbidden, "Permission Denied", "CSRF Failed")
783802 return
784803 }
785804
@@ -797,13 +816,13 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
797816 err := p.SaveSession(rw, req, session)
798817 if err != nil {
799818 logger.Errorf("Error saving session state for %s: %v", remoteAddr, err)
800− p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
819+ p.ErrorPage(rw, req, http.StatusInternalServerError, "Internal Server Error", err.Error())
801820 return
802821 }
803822 http.Redirect(rw, req, redirect, http.StatusFound)
804823 } else {
805824 logger.PrintAuthf(session.Email, req, logger.AuthFailure, "Invalid authentication via OAuth2: unauthorized")
806− p.ErrorPage(rw, http.StatusForbidden, "Permission Denied", "Invalid Account")
825+ p.ErrorPage(rw, req, http.StatusForbidden, "Permission Denied", "Invalid Account")
807826 }
808827}
809828
@@ -885,12 +904,12 @@ func (p *OAuthProxy) Proxy(rw http.ResponseWriter, req *http.Request) {
885904 }
886905
887906 case ErrAccessDenied:
888− p.ErrorPage(rw, http.StatusUnauthorized, "Permission Denied", "Unauthorized")
907+ p.ErrorPage(rw, req, http.StatusUnauthorized, "Permission Denied", "Unauthorized")
889908
890909 default:
891910 // unknown error
892911 logger.Errorf("Unexpected internal error: %v", err)
893− p.ErrorPage(rw, http.StatusInternalServerError,
912+ p.ErrorPage(rw, req, http.StatusInternalServerError,
894913 "Internal Error", "Internal Error")
895914 }
896915}