~gitpocket/gitpocket

8

feat(session): scope main site cookies with the __Host- prefix

commit
34af2a46dac62a9edd1dda31e5d635845c11f6d0 browse tree
parent
e76f2d7b32a09f67e3cfecf761e1901ed081aaff
author
~james <354576047+[email protected]>
signature
Signed by: ~james SHA256:KlzJ0P0gvJcnOYpaxD5yCUw52ImHttTKRjVAEnnYnKg
date
2026-11-13 19:58 UTC

4 files changed, +21 −16

forge/account.go modified

@@ -102,7 +102,7 @@ func (s *Server) resetPassword(w http.ResponseWriter, r *http.Request) {
102102 }
103103
104104 func (s *Server) pendingUser(r *http.Request) (User, bool) {
105- c, err := r.Cookie("pending")
105+ c, err := r.Cookie(pendingCookie)
106106 if err != nil {
107107 return User{}, false
108108 }
@@ -148,10 +148,10 @@ func (s *Server) totpLogin(w http.ResponseWriter, r *http.Request) {
148148 return
149149 }
150150 }
151- if c, err := r.Cookie("pending"); err == nil {
151+ if c, err := r.Cookie(pendingCookie); err == nil {
152152 s.store.db.Exec(`delete from mailtokens where token = ?`, c.Value)
153153 }
154- http.SetCookie(w, &http.Cookie{Name: "pending", Value: "", Path: "/", MaxAge: -1})
154+ http.SetCookie(w, &http.Cookie{Name: pendingCookie, Value: "", Path: "/", HttpOnly: true, Secure: true, MaxAge: -1})
155155 s.startSession(w, u)
156156 http.Redirect(w, r, "/", http.StatusSeeOther)
157157 }

forge/flow_test.go modified

@@ -34,7 +34,7 @@ func post(h http.Handler, path string, form url.Values, cookie string) *httptest
3434 r.Header.Set("Sec-Fetch-Site", "same-origin")
3535 r.RemoteAddr = "192.0.2.1:1000"
3636 if cookie != "" {
37- r.Header.Set("Cookie", "session="+cookie)
37+ r.Header.Set("Cookie", sessionCookie+"="+cookie)
3838 }
3939 w := httptest.NewRecorder()
4040 h.ServeHTTP(w, r)
@@ -45,7 +45,7 @@ func get(h http.Handler, path, cookie string) *httptest.ResponseRecorder {
4545 r := httptest.NewRequest("GET", path, nil)
4646 r.RemoteAddr = "192.0.2.1:1000"
4747 if cookie != "" {
48- r.Header.Set("Cookie", "session="+cookie)
48+ r.Header.Set("Cookie", sessionCookie+"="+cookie)
4949 }
5050 w := httptest.NewRecorder()
5151 h.ServeHTTP(w, r)
@@ -54,7 +54,7 @@ func get(h http.Handler, path, cookie string) *httptest.ResponseRecorder {
5454
5555 func session(w *httptest.ResponseRecorder) string {
5656 for _, c := range w.Result().Cookies() {
57- if c.Name == "session" {
57+ if c.Name == sessionCookie {
5858 return c.Value
5959 }
6060 }
@@ -107,7 +107,7 @@ func TestCrossOriginPostRefused(t *testing.T) {
107107 r := httptest.NewRequest("POST", "/settings/profile", strings.NewReader("display=pwned"))
108108 r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
109109 r.Header.Set("Sec-Fetch-Site", "cross-site")
110- r.Header.Set("Cookie", "session="+id)
110+ r.Header.Set("Cookie", sessionCookie+"="+id)
111111 w := httptest.NewRecorder()
112112 h.ServeHTTP(w, r)
113113 if w.Code != 403 || s.store.Profile(u.ID).Display == "pwned" {
@@ -411,7 +411,7 @@ func TestAttachments(t *testing.T) {
411411 r.Header.Set("Sec-Fetch-Site", "same-origin")
412412 r.RemoteAddr = "192.0.2.1:1000"
413413 if cookie != "" {
414- r.Header.Set("Cookie", "session="+cookie)
414+ r.Header.Set("Cookie", sessionCookie+"="+cookie)
415415 }
416416 w := httptest.NewRecorder()
417417 h.ServeHTTP(w, r)

forge/limit.go modified

@@ -140,7 +140,7 @@ func (s *Server) allowPost(r *http.Request) bool {
140140 if r.Method != "POST" {
141141 return true
142142 }
143- if _, err := r.Cookie("session"); err != nil {
143+ if _, err := r.Cookie(sessionCookie); err != nil {
144144 return true
145145 }
146146 u := s.current(r)

forge/web.go modified

@@ -214,7 +214,7 @@ func (s *Server) fail(w http.ResponseWriter, r *http.Request, code int, msg stri
214214 }
215215
216216 func (s *Server) current(r *http.Request) *User {
217- c, err := r.Cookie("session")
217+ c, err := r.Cookie(sessionCookie)
218218 if err != nil {
219219 return nil
220220 }
@@ -344,7 +344,7 @@ func (s *Server) login(w http.ResponseWriter, r *http.Request) {
344344 }
345345 if s.store.Account(u.ID).TOTP != "" {
346346 token, _ := s.store.CreateMailToken(u.ID, "totp", "")
347- http.SetCookie(w, &http.Cookie{Name: "pending", Value: token, Path: "/", HttpOnly: true, Secure: true, SameSite: http.SameSiteLaxMode, MaxAge: 600})
347+ http.SetCookie(w, &http.Cookie{Name: pendingCookie, Value: token, Path: "/", HttpOnly: true, Secure: true, SameSite: http.SameSiteLaxMode, MaxAge: 600})
348348 http.Redirect(w, r, "/login/totp", http.StatusSeeOther)
349349 return
350350 }
@@ -357,14 +357,14 @@ func (s *Server) startSession(w http.ResponseWriter, u User) {
357357 if err != nil {
358358 return
359359 }
360- http.SetCookie(w, &http.Cookie{Name: "session", Value: id, Path: "/", HttpOnly: true, Secure: true, SameSite: http.SameSiteLaxMode, MaxAge: 90 * 86400})
360+ http.SetCookie(w, &http.Cookie{Name: sessionCookie, Value: id, Path: "/", HttpOnly: true, Secure: true, SameSite: http.SameSiteLaxMode, MaxAge: 90 * 86400})
361361 }
362362
363363 func (s *Server) logout(w http.ResponseWriter, r *http.Request) {
364- if c, err := r.Cookie("session"); err == nil {
364+ if c, err := r.Cookie(sessionCookie); err == nil {
365365 s.store.DeleteSession(c.Value)
366366 }
367- http.SetCookie(w, &http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: -1})
367+ http.SetCookie(w, &http.Cookie{Name: sessionCookie, Value: "", Path: "/", HttpOnly: true, Secure: true, MaxAge: -1})
368368 http.Redirect(w, r, "/", http.StatusSeeOther)
369369 }
370370
@@ -699,7 +699,7 @@ func (s *Server) endSessions(w http.ResponseWriter, r *http.Request) {
699699 return
700700 }
701701 s.store.DeleteSessions(u.ID)
702- http.SetCookie(w, &http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: -1})
702+ http.SetCookie(w, &http.Cookie{Name: sessionCookie, Value: "", Path: "/", HttpOnly: true, Secure: true, MaxAge: -1})
703703 http.Redirect(w, r, "/login", http.StatusSeeOther)
704704 }
705705
@@ -870,7 +870,7 @@ func (s *Server) password(w http.ResponseWriter, r *http.Request) {
870870 http.Redirect(w, r, "/settings/security?error="+template.URLQueryEscaper(err.Error()), http.StatusSeeOther)
871871 return
872872 }
873- if c, err := r.Cookie("session"); err == nil {
873+ if c, err := r.Cookie(sessionCookie); err == nil {
874874 s.store.KeepOnlySession(u.ID, c.Value)
875875 }
876876 http.Redirect(w, r, "/settings/security", http.StatusSeeOther)
@@ -1183,6 +1183,11 @@ func (s *Server) summary(w http.ResponseWriter, r *http.Request, repo Repo) {
11831183
11841184 var displayMath = regexp.MustCompile(`(?m)^( {0,3})\$\$([^$\n]+)\$\$[ \t]*$`)
11851185
1186+const (
1187+ sessionCookie = "__Host-session"
1188+ pendingCookie = "__Host-pending"
1189+)
1190+
11861191 const maxRender = 4 << 20
11871192
11881193 const maxHighlight = 512 << 10