Session codec max-age still 30 days: bring securecookie codecs in line with the 7-day cap #108
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up from the independent review of PR #105 (#66). Not blocking there, because #105 adds a stricter server-side check that shadows this — but the underlying skew remains and should be closed at the source.
The skew
internal/session/session.go:148assignsstore.Optionswholesale. Ingorilla/sessions@v1.4.0,NewCookieStoresets the codec max-age to 30 days viacs.MaxAge(...), and assigningstore.Optionsdirectly never touchesCodecs. So the securecookie layer will still decode a cookie up to 30 days old; only the newexpiredcheck in #105 rejects it.Verified by execution during the #105 review with a throwaway probe: the app's pattern still decodes a cookie past its
Options.MaxAge(returnstrue), whilestore.MaxAge(1)correctly rejects it (false).Why it matters even though #105 shadows it
Before #105 this was a genuine hole — the 7-day absolute cap was enforced only by the browser, and a retained cookie would have been honoured by the server for up to 30 days. #105 closes the exploitable path, but leaves two layers disagreeing about the same policy. That is exactly the shape that breaks later: anyone refactoring the
expiredcheck, or adding a second entry point that decodes a session without going throughIsAuthenticated, silently reopens a 30-day window. Defence in depth belongs at the codec too.Fix: replace the wholesale
store.Optionsassignment withstore.MaxAge(secondsPerDay * sessionMaxAgeDays), which setsOptions.MaxAgeand propagates to every codec. Check whether the same pattern appears anywhere else a store is constructed.Done when: a test proves codec-level rejection of a cookie older than the 7-day cap — i.e. it fails if the
expiredcheck from #105 is removed, so it is genuinely testing the codec and not the new server check.Also from the same review
idleRefreshDivisorfrom 10 to 5 leaves the full suite green (verified). The PR documents "expires up to 10% early, never late" as a deliberate tradeoff, so the constant deserves a test that fails if it drifts — otherwise the documented guarantee is prose only.internal/middleware/middleware.go:217reuses the outererrrather than scoping it inside theif. Harmless, inconsistent with the surrounding style.*fakeClockthey were handed, andfakeClockis duplicated across two test packages. Fold into a shared helper if a third use appears.created_at/last_seen), and it says the timeout is disabled by setting0where the code disables on any non-positive value.Definition of done
make checkgreen via the repo's own entrypoints;.golangci.ymluntouched.