Fix WebSocket CSRF validation failure on Chromium browsers over HTTPS
SameSite=Strict cookies are not sent with WebSocket upgrade requests on Chromium-based browsers (Brave confirmed), causing the CSRF cookie check at connect time to fail with 'csrf cookie mismatch'. This breaks the state_sync namespace, preventing the UI from loading chats. Change SameSite from Strict to Lax for both the Flask session cookie and the JavaScript-set CSRF token cookie. Lax still prevents cross-site POST CSRF while allowing same-origin WebSocket upgrades to include cookies. Fixes #1237
Paolo Calvi committed
Mar 11, 2026 at 00:00 UTC
07f94ef4b5d79834df6164d7b04176062114c599
2 files changed
+2
-2
run_ui.py
+1
-1
@@ -52,7 +52,7 @@ WerkzeugRequest.max_form_memory_size = UPLOAD_LIMIT_BYTES
52
webapp.config.update(
53
JSON_SORT_KEYS=False,
54
SESSION_COOKIE_NAME="session_" + runtime.get_runtime_id(), # bind the session cookie name to runtime id to prevent session collision on same host
55
- SESSION_COOKIE_SAMESITE="Strict",
55
+ SESSION_COOKIE_SAMESITE="Lax",
56
SESSION_PERMANENT=True,
57
PERMANENT_SESSION_LIFETIME=timedelta(days=1),
58
MAX_CONTENT_LENGTH=int(os.getenv("FLASK_MAX_CONTENT_LENGTH", str(UPLOAD_LIMIT_BYTES))),
webui/js/api.js
+1
-1
@@ -219,7 +219,7 @@ export async function getCsrfToken() {
219
if (cookieRuntimeId) {
220
const _secureFlag =
221
window.location.protocol === "https:" ? "; Secure" : "";
222
- document.cookie = `csrf_token_${cookieRuntimeId}=${csrfToken}; SameSite=Strict; Path=/${_secureFlag}`;
222
+ document.cookie = `csrf_token_${cookieRuntimeId}=${csrfToken}; SameSite=Lax; Path=/${_secureFlag}`;
223
} else {
224
console.warn("CSRF runtime id missing; skipping cookie name binding.");
225
}