diff --git a/src/user_engine/identity_state.py b/src/user_engine/identity_state.py index 8bb7c2b..8dec749 100644 --- a/src/user_engine/identity_state.py +++ b/src/user_engine/identity_state.py @@ -17,7 +17,9 @@ from urllib.request import HTTPRedirectHandler, Request, build_opener from user_engine.oidc import cookie_value _IDENTITY_NAME = re.compile(r"^[A-Za-z0-9._@+-]{1,200}$") -_SESSION_TOKEN = re.compile(r"^[A-Za-z0-9._~+/=-]{1,4096}$") +# RFC 6265 cookie-octet: printable ASCII except space, '"', ',', ';' and '\'. +# Authelia session ids use characters such as '%', '^' and '!'. +_SESSION_TOKEN = re.compile(r"^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]{1,4096}$") _PUBLIC_HOST = re.compile(r"[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+") _CLUSTER_HOST = ".svc.cluster.local" diff --git a/tests/test_identity_state.py b/tests/test_identity_state.py index cec1671..ae666d4 100644 --- a/tests/test_identity_state.py +++ b/tests/test_identity_state.py @@ -83,6 +83,14 @@ class IdentityStateParseTests(unittest.TestCase): self.assertIsNone(authelia_session_token("authelia_session=" + ("a" * 4097))) self.assertIsNone(authelia_session_token("")) + def test_cookie_token_accepts_authelia_session_id_characters(self): + # Synthetic value with the punctuation Authelia session ids contain. + value = "Ab3%Xy^Qr!st7Z8&*()[]{}<>?@`|:#$'" + self.assertEqual(value, authelia_session_token(f"authelia_session={value}; other=no")) + for bad in ('a b', 'a"b', "a\\b", "a\tb", "a\x7fb", "aéb"): + with self.subTest(bad=bad): + self.assertIsNone(authelia_session_token(f"authelia_session={bad}")) + def test_lookup_sends_only_the_session_token_and_fails_closed(self): seen = []