Merge branch 'main' into avm99963-monorail
Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266
GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/framework/xsrf.py b/framework/xsrf.py
index 75581ef..bc5ae33 100644
--- a/framework/xsrf.py
+++ b/framework/xsrf.py
@@ -1,7 +1,6 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file or at
-# https://developers.google.com/open-source/licenses/bsd
+# Copyright 2016 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
"""Utility routines for avoiding cross-site-request-forgery."""
from __future__ import print_function
@@ -9,12 +8,12 @@
from __future__ import absolute_import
import base64
+import hashlib
import hmac
-import logging
+import six
import time
# This is a file in the top-level directory that you must edit before deploying
-import settings
from framework import framework_constants
from services import secrets_svc
@@ -43,7 +42,7 @@
XHR_SERVLET_PATH = 'xhr'
-DELIMITER = ':'
+DELIMITER = b':'
def GenerateToken(user_id, servlet_path, token_time=None):
@@ -63,16 +62,16 @@
ValueError: if the XSRF secret was not configured.
"""
token_time = token_time or int(time.time())
- digester = hmac.new(secrets_svc.GetXSRFKey())
- digester.update(str(user_id))
+ digester = hmac.new(secrets_svc.GetXSRFKey(), digestmod=hashlib.md5)
+ digester.update(six.ensure_binary(str(user_id)))
digester.update(DELIMITER)
- digester.update(servlet_path)
+ digester.update(six.ensure_binary(servlet_path))
digester.update(DELIMITER)
- digester.update(str(token_time))
+ digester.update(six.ensure_binary(str(token_time)))
digest = digester.digest()
- token = base64.urlsafe_b64encode('%s%s%d' % (digest, DELIMITER, token_time))
- return token
+ token = base64.urlsafe_b64encode(b'%s%s%d' % (digest, DELIMITER, token_time))
+ return six.ensure_str(token)
def ValidateToken(
@@ -91,7 +90,7 @@
raise TokenIncorrect('missing token')
try:
- decoded = base64.urlsafe_b64decode(str(token))
+ decoded = base64.urlsafe_b64decode(six.ensure_binary(token))
token_time = int(decoded.split(DELIMITER)[-1])
except (TypeError, ValueError):
raise TokenIncorrect('could not decode token')
@@ -104,8 +103,14 @@
# Perform constant time comparison to avoid timing attacks
different = 0
+ # In Python 3, zip(bytes, bytes) gives ints, but in Python 2,
+ # zip(str, str) gives strs. We need to call ord() in Python 2 only.
+ if isinstance(token, six.string_types):
+ token = list(map(ord, token))
+ if isinstance(expected_token, six.string_types):
+ expected_token = list(map(ord, expected_token))
for x, y in zip(token, expected_token):
- different |= ord(x) ^ ord(y)
+ different |= x ^ y
if different:
raise TokenIncorrect(
'presented token does not match expected token: %r != %r' % (