You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/05/18 14:20:59 UTC
(superset) branch master updated: test(security): regression test for session cookie after logout (#24713) (#40201)
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 53d5c41a72c test(security): regression test for session cookie after logout (#24713) (#40201)
53d5c41a72c is described below
commit 53d5c41a72c8b0cd0969e369a49a53ffd234495a
Author: Evan Rusackas <ev...@preset.io>
AuthorDate: Mon May 18 07:20:51 2026 -0700
test(security): regression test for session cookie after logout (#24713) (#40201)
Co-authored-by: Claude Code <no...@anthropic.com>
---
tests/integration_tests/security/api_tests.py | 40 +++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/tests/integration_tests/security/api_tests.py b/tests/integration_tests/security/api_tests.py
index 24e9acc2b69..7512507cf18 100644
--- a/tests/integration_tests/security/api_tests.py
+++ b/tests/integration_tests/security/api_tests.py
@@ -30,6 +30,7 @@ from superset.utils import json
from tests.conftest import with_config
from tests.integration_tests.base_tests import SupersetTestCase
from tests.integration_tests.constants import ADMIN_USERNAME, GAMMA_USERNAME
+from tests.integration_tests.test_app import app
from tests.integration_tests.fixtures.birth_names_dashboard import (
load_birth_names_dashboard_with_slices, # noqa: F401
load_birth_names_data, # noqa: F401
@@ -402,3 +403,42 @@ class TestSecurityRolesApi(SupersetTestCase):
assert sorted(role2_api["user_ids"]) == role2_expected["user_ids"]
assert sorted(role2_api["permission_ids"]) == role2_expected["permission_ids"]
assert role2_api["group_ids"] == role2_expected["group_ids"]
+
+
+class TestLogoutSessionInvalidation(SupersetTestCase):
+ """Regression for #24713: a session cookie captured pre-logout must not grant
+ access after the user logs out. The original report describes copying the
+ session cookie out, calling /logout/, and successfully reusing the cookie in
+ a second browser to bypass authentication."""
+
+ def test_session_cookie_invalidated_after_logout(self):
+ self.login(ADMIN_USERNAME)
+
+ resp_authed = self.client.get("api/v1/dashboard/", follow_redirects=False)
+ assert resp_authed.status_code == 200, (
+ f"Login did not yield an authenticated session "
+ f"(got {resp_authed.status_code})"
+ )
+
+ # Werkzeug 2.3+ exposes the test client's cookies on `_cookies` as a
+ # mapping keyed by (domain, path, key). Snapshot the session cookie
+ # value — this is what a malicious actor would copy out of a browser.
+ captured = None
+ for cookie in self.client._cookies.values():
+ if cookie.key == "session":
+ captured = cookie.value
+ break
+ assert captured, "expected a session cookie after login"
+
+ self.client.get("/logout/", follow_redirects=True)
+
+ # Replay the captured cookie in a fresh client (simulates importing
+ # the cookie into a second browser).
+ replay_client = app.test_client()
+ replay_client.set_cookie("session", captured, domain="localhost")
+
+ resp_replay = replay_client.get("api/v1/dashboard/", follow_redirects=False)
+ assert resp_replay.status_code != 200, (
+ f"Captured session cookie was still accepted after logout "
+ f"(status={resp_replay.status_code}); see issue #24713"
+ )