From 0620ec27aeefcfc3fd891cf0a891bdb7ed96623d Mon Sep 17 00:00:00 2001 From: seth Date: Sat, 8 Aug 2026 21:29:04 +0000 Subject: [PATCH] Pin session cookie name, stop deriving it from APP_NAME Heimdall doesn't ship a config/session.php, so the cookie name falls back to Laravel's framework default: Str::snake((string) env('APP_NAME', 'laravel')) . '_session' Str::snake() only inserts underscores before capital letters; it does not strip characters like "." or spaces. PHP mangles dots in incoming cookie/GET/POST variable names to underscores when parsing a request, so an APP_NAME containing a dot (e.g. "example.com") produces a cookie the app can never read back: it looks for "example.com_session" but PHP only ever hands it "example_com_session" in $_COOKIE. That desyncs the session on every single request, so the CSRF token embedded in any page never matches the token generated on submit, producing a 419 Page Expired on every POST. Reproduced this with a bare curl round-trip (fetch page, extract token+cookie, POST back immediately) with no browser involved at all, which rules out any browser-specific cause like cookie caching or extensions - this is a server-side PHP request-parsing behavior, not a browser quirk. Root cause and fix were worked out with Claude Code: it decrypted the session cookie server-side and confirmed the mismatch with a $_COOKIE probe against config('session.cookie') on a live instance where this was happening. This matches the symptoms in several previously-reported, unresolved 419 issues: - #398 - Getting 419 error code when trying to add apps - #443 - 419 "Sorry, your session has expired" when submitting new app - #590 - 419 error when hitting save - #873 - 419 Page Expired doing any POST requests Setting SESSION_COOKIE explicitly in .env already works around this today (the framework default respects it), but nothing points users at that until they've already hit the bug. Adding config/session.php pins the cookie name to a fixed value by default (still overridable via SESSION_COOKIE) so it no longer depends on APP_NAME at all, fixing it out of the box for new and existing installs alike. App-level config files merge over the framework's defaults key by key (Illuminate\Foundation\Bootstrap\LoadConfiguration), so this only needs to override the one key - verified the rest of session.* still resolves from the framework defaults unchanged. --- config/session.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 config/session.php diff --git a/config/session.php b/config/session.php new file mode 100644 index 000000000..8b3779c2b --- /dev/null +++ b/config/session.php @@ -0,0 +1,19 @@ + 419 on every POST. + // Pinning the cookie name keeps it independent of APP_NAME entirely. + 'cookie' => env('SESSION_COOKIE', 'heimdall_session'), + +];