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"
+        )