More random values for oAuth1 verifier
The oAuth1 verifier was generated as a random number ranging from 1000 to 9999. This small range of numbers is vulnerable to brute-force attacks as described in CWE-330. The verifier is now a 8-character long alphanumerical string, a good compromise between security against guessing and ease of use. SecurityImpact Change-Id: Ibe4a2e57a02c261d85ba6c0d61696f134c54443e Closes-Bug: #1236675
This commit is contained in:
parent
314c0325fc
commit
fd02a9c3d0
@ -204,7 +204,8 @@ class OAuth1(object):
|
||||
token_ref = self._get_request_token(session, request_token_id)
|
||||
token_dict = token_ref.to_dict()
|
||||
token_dict['authorizing_user_id'] = user_id
|
||||
token_dict['verifier'] = str(random.randint(1000, 9999))
|
||||
token_dict['verifier'] = ''.join(random.sample(core.VERIFIER_CHARS,
|
||||
8))
|
||||
token_dict['role_ids'] = jsonutils.dumps(role_ids)
|
||||
|
||||
new_token = RequestToken.from_dict(token_dict)
|
||||
|
@ -17,6 +17,7 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import abc
|
||||
import string
|
||||
|
||||
import oauthlib.common
|
||||
from oauthlib import oauth1
|
||||
@ -39,6 +40,11 @@ AuthorizationEndpoint = oauth1.AuthorizationEndpoint
|
||||
SIG_HMAC = oauth1.SIGNATURE_HMAC
|
||||
RequestTokenEndpoint = oauth1.RequestTokenEndpoint
|
||||
oRequest = oauthlib.common.Request
|
||||
# The characters used to generate verifiers are limited to alphanumerical
|
||||
# values for ease of manual entry. Commonly confused characters are omitted.
|
||||
VERIFIER_CHARS = string.ascii_letters + string.digits
|
||||
CONFUSED_CHARS = 'jiIl1oO0'
|
||||
VERIFIER_CHARS = ''.join(c for c in VERIFIER_CHARS if c not in CONFUSED_CHARS)
|
||||
|
||||
|
||||
class Token(object):
|
||||
|
@ -58,10 +58,8 @@ class OAuthValidator(oauth1.RequestValidator):
|
||||
return set(nonce) <= self.safe_characters
|
||||
|
||||
def check_verifier(self, verifier):
|
||||
try:
|
||||
return 1000 <= int(verifier) <= 9999
|
||||
except ValueError:
|
||||
return False
|
||||
return (all(i in oauth1.VERIFIER_CHARS for i in verifier) and
|
||||
len(verifier) == 8)
|
||||
|
||||
def get_client_secret(self, client_key, request):
|
||||
client = self.oauth_api.get_consumer_with_secret(client_key)
|
||||
|
@ -20,6 +20,7 @@ from six.moves import urllib
|
||||
from keystone import config
|
||||
from keystone.contrib import oauth1
|
||||
from keystone.contrib.oauth1 import controllers
|
||||
from keystone.contrib.oauth1 import core
|
||||
from keystone import exception
|
||||
from keystone.tests import test_v3
|
||||
|
||||
@ -256,6 +257,8 @@ class OAuthFlowTests(OAuth1Tests):
|
||||
body = {'roles': [{'id': self.role_id}]}
|
||||
resp = self.put(url, body=body, expected_status=200)
|
||||
self.verifier = resp.result['token']['oauth_verifier']
|
||||
self.assertTrue(all(i in core.VERIFIER_CHARS for i in self.verifier))
|
||||
self.assertEqual(8, len(self.verifier))
|
||||
|
||||
self.request_token.set_verifier(self.verifier)
|
||||
url, headers = self._create_access_token(self.consumer,
|
||||
|
Loading…
Reference in New Issue
Block a user