Replace CSRF cookie with CrossOriginProtection (#36183)

Removes the CSRF cookie in favor of
[`CrossOriginProtection`](https://pkg.go.dev/net/http#CrossOriginProtection)
which relies purely on HTTP headers.

Fixes: https://github.com/go-gitea/gitea/issues/11188
Fixes: https://github.com/go-gitea/gitea/issues/30333
Helps: https://github.com/go-gitea/gitea/issues/35107

TODOs:

- [x] Fix tests
- [ ] Ideally add tests to validates the protection

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
silverwind
2025-12-25 11:33:34 +01:00
committed by GitHub
parent eddf875992
commit 42d294941c
207 changed files with 178 additions and 1196 deletions
+5 -11
View File
@@ -125,7 +125,7 @@ type ldapAuthOptions struct {
groupTeamMapRemoval string
}
func (te *ldapTestEnv) buildAuthSourcePayload(csrf string, opts ...ldapAuthOptions) map[string]string {
func (te *ldapTestEnv) buildAuthSourcePayload(opts ...ldapAuthOptions) map[string]string {
opt := util.OptionalArg(opts)
// Modify user filter to test group filter explicitly
userFilter := "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))"
@@ -134,7 +134,6 @@ func (te *ldapTestEnv) buildAuthSourcePayload(csrf string, opts ...ldapAuthOptio
}
return map[string]string{
"_csrf": csrf,
"type": "2",
"name": "ldap",
"host": te.serverHost,
@@ -164,8 +163,7 @@ func (te *ldapTestEnv) buildAuthSourcePayload(csrf string, opts ...ldapAuthOptio
func (te *ldapTestEnv) addAuthSource(t *testing.T, opts ...ldapAuthOptions) {
session := loginUser(t, "user1")
csrf := GetUserCSRFToken(t, session)
req := NewRequestWithValues(t, "POST", "/-/admin/auths/new", te.buildAuthSourcePayload(csrf, opts...))
req := NewRequestWithValues(t, "POST", "/-/admin/auths/new", te.buildAuthSourcePayload(opts...))
session.MakeRequest(t, req, http.StatusSeeOther)
}
@@ -212,13 +210,12 @@ func TestLDAPAuthChange(t *testing.T) {
req = NewRequest(t, "GET", href)
resp = session.MakeRequest(t, req, http.StatusOK)
doc = NewHTMLParser(t, resp.Body)
csrf := doc.GetCSRF()
host, _ := doc.Find(`input[name="host"]`).Attr("value")
assert.Equal(t, te.serverHost, host)
binddn, _ := doc.Find(`input[name="bind_dn"]`).Attr("value")
assert.Equal(t, "uid=gitea,ou=service,dc=planetexpress,dc=com", binddn)
req = NewRequestWithValues(t, "POST", href, te.buildAuthSourcePayload(csrf, ldapAuthOptions{groupTeamMapRemoval: "off"}))
req = NewRequestWithValues(t, "POST", href, te.buildAuthSourcePayload(ldapAuthOptions{groupTeamMapRemoval: "off"}))
session.MakeRequest(t, req, http.StatusSeeOther)
req = NewRequest(t, "GET", href)
@@ -267,8 +264,7 @@ func TestLDAPUserSyncWithEmptyUsernameAttribute(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user1")
csrf := GetUserCSRFToken(t, session)
payload := te.buildAuthSourcePayload(csrf)
payload := te.buildAuthSourcePayload()
payload["attribute_username"] = ""
req := NewRequestWithValues(t, "POST", "/-/admin/auths/new", payload)
session.MakeRequest(t, req, http.StatusSeeOther)
@@ -285,7 +281,6 @@ func TestLDAPUserSyncWithEmptyUsernameAttribute(t *testing.T) {
for _, u := range te.gitLDAPUsers {
req := NewRequestWithValues(t, "POST", "/user/login", map[string]string{
"_csrf": csrf,
"user_name": u.UserName,
"password": u.Password,
})
@@ -512,8 +507,7 @@ func TestLDAPPreventInvalidGroupTeamMap(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user1")
csrf := GetUserCSRFToken(t, session)
payload := te.buildAuthSourcePayload(csrf, ldapAuthOptions{groupTeamMap: `{"NOT_A_VALID_JSON"["MISSING_DOUBLE_POINT"]}`, groupTeamMapRemoval: "off"})
payload := te.buildAuthSourcePayload(ldapAuthOptions{groupTeamMap: `{"NOT_A_VALID_JSON"["MISSING_DOUBLE_POINT"]}`, groupTeamMapRemoval: "off"})
req := NewRequestWithValues(t, "POST", "/-/admin/auths/new", payload)
session.MakeRequest(t, req, http.StatusOK) // StatusOK = failed, StatusSeeOther = ok
}