mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Store the request path in the nonce for the android cookie. Prevents replay attacks against more than a single URL
Test for android cross url replay attack prevention
This commit is contained in:
parent
1ea0f8ddab
commit
4c1cd70233
@ -200,15 +200,16 @@ class AuthController(object):
|
|||||||
return pw and self.user_credentials.get(un) == pw
|
return pw and self.user_credentials.get(un) == pw
|
||||||
|
|
||||||
def __call__(self, data, endpoint):
|
def __call__(self, data, endpoint):
|
||||||
http_auth_needed = not (endpoint.android_workaround and self.validate_android_cookie(data.cookies.get(self.ANDROID_COOKIE)))
|
path = encode_path(*data.path)
|
||||||
|
http_auth_needed = not (endpoint.android_workaround and self.validate_android_cookie(path, data.cookies.get(self.ANDROID_COOKIE)))
|
||||||
if http_auth_needed:
|
if http_auth_needed:
|
||||||
self.do_http_auth(data, endpoint)
|
self.do_http_auth(data, endpoint)
|
||||||
if endpoint.android_workaround:
|
if endpoint.android_workaround:
|
||||||
data.outcookie[self.ANDROID_COOKIE] = synthesize_nonce(self.key_order, self.realm, self.secret)
|
data.outcookie[self.ANDROID_COOKIE] = synthesize_nonce(self.key_order, path, self.secret)
|
||||||
data.outcookie[self.ANDROID_COOKIE]['path'] = encode_path(*data.path)
|
data.outcookie[self.ANDROID_COOKIE]['path'] = path
|
||||||
|
|
||||||
def validate_android_cookie(self, cookie):
|
def validate_android_cookie(self, path, cookie):
|
||||||
return cookie and validate_nonce(self.key_order, cookie, self.realm, self.secret) and not is_nonce_stale(cookie, self.max_age_seconds)
|
return cookie and validate_nonce(self.key_order, cookie, path, self.secret) and not is_nonce_stale(cookie, self.max_age_seconds)
|
||||||
|
|
||||||
def do_http_auth(self, data, endpoint):
|
def do_http_auth(self, data, endpoint):
|
||||||
auth = data.inheaders.get('Authorization')
|
auth = data.inheaders.get('Authorization')
|
||||||
|
@ -26,6 +26,10 @@ def auth(ctx, data):
|
|||||||
def android(ctx, data):
|
def android(ctx, data):
|
||||||
return 'android'
|
return 'android'
|
||||||
|
|
||||||
|
@endpoint('/android2', auth_required=True, android_workaround=True)
|
||||||
|
def android2(ctx, data):
|
||||||
|
return 'android2'
|
||||||
|
|
||||||
def router(prefer_basic_auth=False):
|
def router(prefer_basic_auth=False):
|
||||||
from calibre.srv.auth import AuthController
|
from calibre.srv.auth import AuthController
|
||||||
return Router(globals().itervalues(), auth_controller=AuthController(
|
return Router(globals().itervalues(), auth_controller=AuthController(
|
||||||
@ -199,4 +203,11 @@ class TestAuth(BaseTest):
|
|||||||
r = urllib2.build_opener(cookie_handler).open(url)
|
r = urllib2.build_opener(cookie_handler).open(url)
|
||||||
self.ae(r.getcode(), httplib.OK)
|
self.ae(r.getcode(), httplib.OK)
|
||||||
self.ae(r.read(), b'android')
|
self.ae(r.read(), b'android')
|
||||||
|
# Test that a replay attack against a different URL does not work
|
||||||
|
try:
|
||||||
|
urllib2.build_opener(cookie_handler).open(url+'2')
|
||||||
|
assert ('Replay attack succeeded')
|
||||||
|
except urllib2.HTTPError as e:
|
||||||
|
self.ae(e.code, httplib.UNAUTHORIZED)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user