diff --git a/src/idpproxy/state.py b/src/idpproxy/state.py index 1529d29..8e251f7 100644 --- a/src/idpproxy/state.py +++ b/src/idpproxy/state.py @@ -161,8 +161,17 @@ def parse_cookie(self, value): parts = value.split("|") if len(parts) != 3: return None - # verify the cookie signature - if self.cookie_signature(parts[0], parts[1]) != parts[2]: + # Verify the cookie signature in a constant time manner to prevent + # attackers from guessing the correct signature value (code snippet + # borrowed from http://rdist.root.org/2009/05/28/ \ + # timing-attack-in-google-keyczar-library/ ). + correctMac = self.cookie_signature(parts[0], parts[1]) + if len(correctMac) != len(parts[2]): + raise Exception("Invalid cookie signature %r", value) + result = 0 + for x, y in zip(correctMac, parts[2]): + result |= ord(x) ^ ord(y) + if result: raise Exception("Invalid cookie signature %r", value) try: @@ -266,4 +275,4 @@ def info(self): return None def authn_service(self): - return self._cache.get(self.group, self.session_id)["service"] \ No newline at end of file + return self._cache.get(self.group, self.session_id)["service"]