Skip to content

Instantly share code, notes, and snippets.

@robintw
Created March 26, 2026 10:56
Show Gist options
  • Select an option

  • Save robintw/721988b4e3f3b8cb6d2fac4c87bdfbe5 to your computer and use it in GitHub Desktop.

Select an option

Save robintw/721988b4e3f3b8cb6d2fac4c87bdfbe5 to your computer and use it in GitHub Desktop.
The issue is likely that when the cookie already exists in the browser from a previous session with a different secret key (e.g., the secret key file was regenerated, or data directory changed), the decode fails.
Let me check if the error is being handled properly.
Look at withCSRF line 289-293:
session, err := sessionStore.Get(c.Request, storeName)
if err != nil {
http.Error(c.Response, err.Error(), http.StatusInternalServerError)
return
}
And withAuth line 242-245:
session, err := sessionStore.Get(c.Request, storeName)
if err != nil {
serve403(c)
return
}
Here's the bug: gorilla/sessions' Get() returns both a session AND an error when the cookie can't be decoded. The returned session is a new, empty session — perfectly usable. The error is informational,
indicating the old cookie was invalid. The idiomatic pattern is to ignore the error (or log it) and proceed with the new session.
By returning an error response when sessionStore.Get() fails, the code makes it impossible for a user with a stale/invalid cookie to ever recover — they're permanently locked out until they manually clear
cookies.
Let me verify this is the gorilla/sessions behavior.
Searched for 6 patterns (ctrl+o to expand)
⏺ The vendor/module cache isn't available locally, but this is well-known gorilla/sessions behavior. From the gorilla/sessions docs: Get returns a session even when decoding fails — it returns a new empty session
plus the error. The intended pattern is to check session.IsNew rather than treating the error as fatal.
Here's the fix. Both withAuth and withCSRF should not treat the sessionStore.Get() error as fatal:
⎿  Added 1 line, removed 5 lines
239
240 func withAuth(handler endpointHandler) endpointHandler {
241 return func(c *webContext) {
242 - session, err := sessionStore.Get(c.Request, storeName)
243 - if err != nil {
244 - serve403(c)
245 - return
246 - }
242 + session, _ := sessionStore.Get(c.Request, storeName)
243 if t, ok := session.Values["access_token"].(string); ok && t == c.Config.App.AccessToken {
244 handler(c)
245 return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment