Skip to content

fix(auth): harden session cookie (HttpOnly/Secure/SameSite)#258

Open
ttonyxx wants to merge 1 commit into
security/01-verify-google-id-tokenfrom
security/02-session-cookie-flags
Open

fix(auth): harden session cookie (HttpOnly/Secure/SameSite)#258
ttonyxx wants to merge 1 commit into
security/01-verify-google-id-tokenfrom
security/02-session-cookie-flags

Conversation

@ttonyxx

@ttonyxx ttonyxx commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Severity: 🟠 High — session theft via XSS / insecure transport

Stacked on #257. Review/merge that first; this PR targets its branch so the diff shows only the cookie change.

The problem

The session is a signed cookie (cookie.NewStore), but no options were ever set on the store. The underlying gorilla defaults leave all security flags off, so the session cookie was:

  • No HttpOnly → readable by page JavaScript; any XSS or malicious script can steal the session and impersonate the user.
  • No Secure → sent over plain HTTP; vulnerable to interception / SSL-strip.
  • No explicit SameSite → weaker CSRF posture than necessary.

The fix

store.Options(sessions.Options{
    Path:     "/",
    MaxAge:   60 * 60 * 24 * 30,
    HttpOnly: true,
    Secure:   utils.IsRelease(), // HTTPS-only in prod, off for localhost dev
    SameSite: http.SameSiteLaxMode,
})

Secure is gated on utils.IsRelease() so local development over http://localhost:8080 keeps working, while production (same-origin HTTPS) gets the hardened cookie. SameSite=Lax is safe for the same-origin production setup and the same-site localhost dev setup.

🤖 Generated with Claude Code

## Why this change is needed

The session is stored in a signed cookie via the gorilla cookie store, but no
cookie options were configured. The gorilla defaults leave every security flag
off, which means the `session` cookie was:

- readable by page JavaScript (no `HttpOnly`) — any XSS, or a malicious
  third-party script, could exfiltrate the session and impersonate the user;
- sent over plain HTTP (no `Secure`) — the session could leak over an
  unencrypted connection / be stripped by an active network attacker;
- emitted with no explicit `SameSite` — weaker CSRF posture than necessary.

## What this does

Configures the cookie store options:

- `HttpOnly: true` always — keep the session out of reach of JavaScript.
- `Secure: utils.IsRelease()` — require HTTPS in production while still
  allowing `http://localhost` during local development.
- `SameSite=Lax` — mitigate CSRF while still permitting top-level navigations.
- Explicit `Path` and 30-day `MaxAge`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ttonyxx ttonyxx force-pushed the security/02-session-cookie-flags branch from d2919b6 to e3c36eb Compare May 29, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant