From 7ae9f48542dd98bd89879282833d9c85a1ddc505 Mon Sep 17 00:00:00 2001 From: Yusuf Simonson Date: Wed, 7 Jan 2015 11:01:55 -0500 Subject: [PATCH 1/2] Handle bad xsrf tokens more gracefully --- tornado/web.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tornado/web.py b/tornado/web.py index 2d1dac0f..71751848 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1124,7 +1124,11 @@ class RequestHandler(object): if m: version = int(m.group(1)) if version == 2: - _, mask, masked_token, timestamp = cookie.split("|") + try: + _, mask, masked_token, timestamp = cookie.split("|") + except ValueError: + return None, None, None + mask = binascii.a2b_hex(utf8(mask)) token = _websocket_mask( mask, binascii.a2b_hex(utf8(masked_token))) From 2a24e12ace222ee0c1e7dabb40c8e032f7734bbc Mon Sep 17 00:00:00 2001 From: Yusuf Simonson Date: Mon, 12 Jan 2015 10:45:52 -0500 Subject: [PATCH 2/2] More aggressive capturing of xsrf cookie errors --- tornado/web.py | 52 +++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/tornado/web.py b/tornado/web.py index 71751848..3c7da658 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -1120,32 +1120,36 @@ class RequestHandler(object): """Convert a cookie string into a the tuple form returned by _get_raw_xsrf_token. """ - m = _signed_value_version_re.match(utf8(cookie)) - if m: - version = int(m.group(1)) - if version == 2: - try: - _, mask, masked_token, timestamp = cookie.split("|") - except ValueError: - return None, None, None - mask = binascii.a2b_hex(utf8(mask)) - token = _websocket_mask( - mask, binascii.a2b_hex(utf8(masked_token))) - timestamp = int(timestamp) - return version, token, timestamp + try: + m = _signed_value_version_re.match(utf8(cookie)) + + if m: + version = int(m.group(1)) + if version == 2: + _, mask, masked_token, timestamp = cookie.split("|") + + mask = binascii.a2b_hex(utf8(mask)) + token = _websocket_mask( + mask, binascii.a2b_hex(utf8(masked_token))) + timestamp = int(timestamp) + return version, token, timestamp + else: + # Treat unknown versions as not present instead of failing. + raise Exception("Unknown xsrf cookie version") else: - # Treat unknown versions as not present instead of failing. - return None, None, None - else: - version = 1 - try: - token = binascii.a2b_hex(utf8(cookie)) - except (binascii.Error, TypeError): - token = utf8(cookie) - # We don't have a usable timestamp in older versions. - timestamp = int(time.time()) - return (version, token, timestamp) + version = 1 + try: + token = binascii.a2b_hex(utf8(cookie)) + except (binascii.Error, TypeError): + token = utf8(cookie) + # We don't have a usable timestamp in older versions. + timestamp = int(time.time()) + return (version, token, timestamp) + except Exception: + # Catch exceptions and return nothing instead of failing. + gen_log.debug("Uncaught exception in _decode_xsrf_token", exc_info=True) + return None, None, None def check_xsrf_cookie(self): """Verifies that the ``_xsrf`` cookie matches the ``_xsrf`` argument.