From 1050ada43b66599375cecb6e80b469ae93884f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Fri, 21 May 2021 11:38:41 +0200 Subject: [PATCH] Improved internaldb password security (sha3_256) and added extra security to uds cookie --- .../src/uds/auths/InternalDB/authenticator.py | 5 ++--- server/src/uds/core/auths/auth.py | 5 +++-- server/src/uds/core/managers/crypto.py | 22 ++++++++++++++----- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/server/src/uds/auths/InternalDB/authenticator.py b/server/src/uds/auths/InternalDB/authenticator.py index faa793a2..cf8569ff 100644 --- a/server/src/uds/auths/InternalDB/authenticator.py +++ b/server/src/uds/auths/InternalDB/authenticator.py @@ -111,9 +111,8 @@ class InternalDBAuth(auths.Authenticator): if user.parent: # Direct auth not allowed for "derived" users return False - # Internal Db Auth has its own groups, and if it active it is valid - if user.password == cryptoManager().hash(credentials): - # hashlib.sha1(credentials.encode('utf-8')).hexdigest(): + # Internal Db Auth has its own groups. (That is, no external source). If a group is active it is valid + if cryptoManager().checkHash(credentials, user.password): groupsManager.validate([g.name for g in user.groups.all()]) return True return False diff --git a/server/src/uds/core/auths/auth.py b/server/src/uds/core/auths/auth.py index 63ef5513..c6ca9a51 100644 --- a/server/src/uds/core/auths/auth.py +++ b/server/src/uds/core/auths/auth.py @@ -71,6 +71,7 @@ USER_KEY = 'uk' PASS_KEY = 'pk' EXPIRY_KEY = 'ek' ROOT_ID = -20091204 # Any negative number will do the trick +UDS_COOKIE_LENGTH = 48 RT = typing.TypeVar('RT') @@ -84,12 +85,12 @@ def getUDSCookie( Generates a random cookie for uds, used, for example, to encript things """ if 'uds' not in request.COOKIES: - cookie = cryptoManager().randomString(48) + cookie = cryptoManager().randomString(UDS_COOKIE_LENGTH) if response is not None: response.set_cookie('uds', cookie, samesite='Lax') request.COOKIES['uds'] = cookie else: - cookie = request.COOKIES['uds'] + cookie = request.COOKIES['uds'][:UDS_COOKIE_LENGTH] if response and force: response.set_cookie('uds', cookie) diff --git a/server/src/uds/core/managers/crypto.py b/server/src/uds/core/managers/crypto.py index 9750e946..21c2d786 100644 --- a/server/src/uds/core/managers/crypto.py +++ b/server/src/uds/core/managers/crypto.py @@ -87,7 +87,7 @@ class CryptoManager: def encrypt(self, value: str) -> str: return codecs.encode( - self._rsa.public_key().encrypt( + self._rsa.public_key().encrypt( # type: ignore value.encode(), padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), @@ -103,7 +103,7 @@ class CryptoManager: try: # First, try new "cryptografy" decrpypting - decrypted: bytes = self._rsa.decrypt( + decrypted: bytes = self._rsa.decrypt( # type: ignore data, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), @@ -221,12 +221,24 @@ class CryptoManager: def hash(self, value: typing.Union[str, bytes]) -> str: if isinstance(value, str): - value = value.encode('utf-8') + value = value.encode() if not value: return '' - return str(hashlib.sha1(value).hexdigest()) + return '{SHA256}' + str(hashlib.sha3_256(value).hexdigest()) + + def checkHash(self, value: typing.Union[str, bytes], hash: str) -> bool: + if isinstance(value, str): + value = value.encode() + + if not value: + return not hash + + if hash[:8] == '{SHA256}': + return str(hashlib.sha3_256(value).hexdigest()) == hash[8:] + else: # Old sha1 + return hash == str(hashlib.sha1(value).hexdigest()) def uuid(self, obj: typing.Any = None) -> str: """ @@ -246,5 +258,5 @@ class CryptoManager: ).lower() # I believe uuid returns a lowercase uuid always, but in case... :) def randomString(self, length: int = 40, digits: bool = True) -> str: - base = string.ascii_lowercase + (string.digits if digits else '') + base = string.ascii_letters + (string.digits if digits else '') return ''.join(random.SystemRandom().choices(base, k=length))