Use constant-time string compare for /info requests

If you GET /info?swiftinfo_sig=<HMAC>&swiftinfo_expires=<TIME>, then
the response contains any admin-only information that's been
registered (via calls to register_swift_info(admin=True)).

The bad news is that the info controller isn't using streq_const_time
to compare the valid HMAC signatures with the passed-in one, leading
to a possible timing attack.

The good news is that this isn't a security hole since there's
absolutely nothing interesting in the admin-only section yet, so even
if an attacker does suss out a valid signature, they don't learn
anything. However, we should still fix this in case anything
interesting ever does get added.

Change-Id: I28b6814def67200ddaa6272e09f6a55fb517fd97
This commit is contained in:
Samuel Merritt 2014-01-15 11:01:52 -08:00
parent 233f539788
commit 13c89766b1

View File

@ -15,7 +15,8 @@
from time import time
from swift.common.utils import public, get_hmac, get_swift_info, json
from swift.common.utils import public, get_hmac, get_swift_info, json, \
streq_const_time
from swift.proxy.controllers.base import Controller, delay_denial
from swift.common.swob import HTTPOk, HTTPForbidden, HTTPUnauthorized
@ -82,7 +83,12 @@ class InfoController(Controller):
expires,
self.admin_key))
if sig not in valid_sigs:
# While it's true that any() will short-circuit, this doesn't
# affect the timing-attack resistance since the only way this will
# short-circuit is when a valid signature is passed in.
is_valid_hmac = any(streq_const_time(valid_sig, sig)
for valid_sig in valid_sigs)
if not is_valid_hmac:
return HTTPUnauthorized(request=req)
headers = {}