mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 00:11:04 +00:00 
			
		
		
		
	Merge '[BUG] prevent removing session cookie when redirect_uri query contains ://' (#2590)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/2590 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org>
This commit is contained in:
		
				commit
				
					
						6313b89e53
					
				
			
		
					 2 changed files with 59 additions and 1 deletions
				
			
		| 
						 | 
					@ -256,7 +256,7 @@ func (b *Base) Redirect(location string, status ...int) {
 | 
				
			||||||
		code = status[0]
 | 
							code = status[0]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if strings.Contains(location, "://") || strings.HasPrefix(location, "//") {
 | 
						if httplib.IsRiskyRedirectURL(location) {
 | 
				
			||||||
		// Some browsers (Safari) have buggy behavior for Cookie + Cache + External Redirection, eg: /my-path => https://other/path
 | 
							// Some browsers (Safari) have buggy behavior for Cookie + Cache + External Redirection, eg: /my-path => https://other/path
 | 
				
			||||||
		// 1. the first request to "/my-path" contains cookie
 | 
							// 1. the first request to "/my-path" contains cookie
 | 
				
			||||||
		// 2. some time later, the request to "/my-path" doesn't contain cookie (caused by Prevent web tracking)
 | 
							// 2. some time later, the request to "/my-path" doesn't contain cookie (caused by Prevent web tracking)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -470,6 +470,64 @@ func TestSignInOAuthCallbackSignIn(t *testing.T) {
 | 
				
			||||||
	assert.Greater(t, userAfterLogin.LastLoginUnix, userGitLab.LastLoginUnix)
 | 
						assert.Greater(t, userAfterLogin.LastLoginUnix, userGitLab.LastLoginUnix)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestSignInOAuthCallbackRedirectToEscaping(t *testing.T) {
 | 
				
			||||||
 | 
						defer tests.PrepareTestEnv(t)()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// OAuth2 authentication source GitLab
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						gitlabName := "gitlab"
 | 
				
			||||||
 | 
						gitlab := addAuthSource(t, authSourcePayloadGitLabCustom(gitlabName))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// Create a user as if it had been previously been created by the GitLab
 | 
				
			||||||
 | 
						// authentication source.
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						userGitLabUserID := "5678"
 | 
				
			||||||
 | 
						userGitLab := &user_model.User{
 | 
				
			||||||
 | 
							Name:        "gitlabuser",
 | 
				
			||||||
 | 
							Email:       "gitlabuser@example.com",
 | 
				
			||||||
 | 
							Passwd:      "gitlabuserpassword",
 | 
				
			||||||
 | 
							Type:        user_model.UserTypeIndividual,
 | 
				
			||||||
 | 
							LoginType:   auth_model.OAuth2,
 | 
				
			||||||
 | 
							LoginSource: gitlab.ID,
 | 
				
			||||||
 | 
							LoginName:   userGitLabUserID,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer createUser(context.Background(), t, userGitLab)()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// A request for user information sent to Goth will return a
 | 
				
			||||||
 | 
						// goth.User exactly matching the user created above.
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						defer mockCompleteUserAuth(func(res http.ResponseWriter, req *http.Request) (goth.User, error) {
 | 
				
			||||||
 | 
							return goth.User{
 | 
				
			||||||
 | 
								Provider: gitlabName,
 | 
				
			||||||
 | 
								UserID:   userGitLabUserID,
 | 
				
			||||||
 | 
								Email:    userGitLab.Email,
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						})()
 | 
				
			||||||
 | 
						req := NewRequest(t, "GET", fmt.Sprintf("/user/oauth2/%s/callback?code=XYZ&state=XYZ", gitlabName))
 | 
				
			||||||
 | 
						req.AddCookie(&http.Cookie{
 | 
				
			||||||
 | 
							Name:  "redirect_to",
 | 
				
			||||||
 | 
							Value: "/login/oauth/authorize?redirect_uri=https%3A%2F%2Ftranslate.example.org",
 | 
				
			||||||
 | 
							Path:  "/",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						resp := MakeRequest(t, req, http.StatusSeeOther)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hasNewSessionCookie := false
 | 
				
			||||||
 | 
						sessionCookieName := setting.SessionConfig.CookieName
 | 
				
			||||||
 | 
						for _, c := range resp.Result().Cookies() {
 | 
				
			||||||
 | 
							if c.Name == sessionCookieName {
 | 
				
			||||||
 | 
								hasNewSessionCookie = true
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log("Got cookie", c.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.True(t, hasNewSessionCookie, "Session cookie %q is missing", sessionCookieName)
 | 
				
			||||||
 | 
						assert.Equal(t, "/login/oauth/authorize?redirect_uri=https://translate.example.org", test.RedirectURL(resp))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestSignUpViaOAuthWithMissingFields(t *testing.T) {
 | 
					func TestSignUpViaOAuthWithMissingFields(t *testing.T) {
 | 
				
			||||||
	defer tests.PrepareTestEnv(t)()
 | 
						defer tests.PrepareTestEnv(t)()
 | 
				
			||||||
	// enable auto-creation of accounts via OAuth2
 | 
						// enable auto-creation of accounts via OAuth2
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue