@@ -870,9 +870,22 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
870870 return
871871 }
872872
873− csrf, err := cookies.LoadCSRFCookie(req, p.CookieOptions)
873+ nonce, appRedirect, err := decodeState(req.Form.Get("state"), p.encodeState)
874+ if err != nil {
875+ logger.Errorf("Error while parsing OAuth2 state: %v", err)
876+ p.ErrorPage(rw, req, http.StatusInternalServerError, err.Error())
877+ return
878+ }
879+
880+ // calculate the cookie name
881+ cookieName := cookies.GenerateCookieName(p.CookieOptions, nonce)
882+ // Try to find the CSRF cookie and decode it
883+ csrf, err := cookies.LoadCSRFCookie(req, cookieName, p.CookieOptions)
874884 if err != nil {
875− logger.Println(req, logger.AuthFailure, "Invalid authentication via OAuth2. Error while loading CSRF cookie:", err.Error())
885+ // There are a lot of issues opened complaining about missing CSRF cookies.
886+ // Try to log the INs and OUTs of OAuthProxy, to be easier to analyse these issues.
887+ LoggingCSRFCookiesInOAuthCallback(req, cookieName)
888+ logger.Println(req, logger.AuthFailure, "Invalid authentication via OAuth2: unable to obtain CSRF cookie: %s (state=%s)", err, nonce)
876889 p.ErrorPage(rw, req, http.StatusForbidden, err.Error(), "Login Failed: Unable to find a valid CSRF token. Please try again.")
877890 return
878891 }
@@ -893,13 +906,6 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
893906
894907 csrf.ClearCookie(rw, req)
895908
896− nonce, appRedirect, err := decodeState(req.Form.Get("state"), p.encodeState)
897− if err != nil {
898− logger.Errorf("Error while parsing OAuth2 state: %v", err)
899− p.ErrorPage(rw, req, http.StatusInternalServerError, err.Error())
900− return
901− }
902−
903909 if !csrf.CheckOAuthState(nonce) {
904910 logger.PrintAuthf(session.Email, req, logger.AuthFailure, "Invalid authentication via OAuth2: CSRF token mismatch, potential attack")
905911 p.ErrorPage(rw, req, http.StatusForbidden, "CSRF token mismatch, potential attack", "Login Failed: Unable to find a valid CSRF token. Please try again.")
@@ -1297,3 +1303,27 @@ func (p *OAuthProxy) errorJSON(rw http.ResponseWriter, code int) {
12971303 // application/json
12981304 rw.Write([]byte("{}"))
12991305}
1306+
1307+// LoggingCSRFCookiesInOAuthCallback Log all CSRF cookies found in HTTP request OAuth callback,
1308+// which were successfully parsed
1309+func LoggingCSRFCookiesInOAuthCallback(req *http.Request, cookieName string) {
1310+ cookies := req.Cookies()
1311+ if len(cookies) == 0 {
1312+ logger.Println(req, logger.AuthFailure, "No cookies were found in OAuth callback.")
1313+ return
1314+ }
1315+
1316+ for _, c := range cookies {
1317+ if cookieName == c.Name {
1318+ logger.Println(req, logger.AuthFailure, "CSRF cookie %s was found in OAuth callback.", c.Name)
1319+ return
1320+ }
1321+
1322+ if strings.HasSuffix(c.Name, "_csrf") {
1323+ logger.Println(req, logger.AuthFailure, "CSRF cookie %s was found in OAuth callback, but it is not the expected one (%s).", c.Name, cookieName)
1324+ return
1325+ }
1326+ }
1327+
1328+ logger.Println(req, logger.AuthFailure, "Cookies were found in OAuth callback, but none was a CSRF cookie.")
1329+}