diff --git a/server/src/uds/core/managers/crypto.py b/server/src/uds/core/managers/crypto.py index 5a5407b6b..2448d7d68 100644 --- a/server/src/uds/core/managers/crypto.py +++ b/server/src/uds/core/managers/crypto.py @@ -36,10 +36,11 @@ import codecs import datetime import struct import re -import random import string import logging import typing +import secrets +import time from cryptography import x509 @@ -134,9 +135,7 @@ class CryptoManager(metaclass=singleton.Singleton): modes.CBC(b'udsinitvectoruds'), backend=default_backend(), ) - rndStr = self.randomString( - 16 - ).encode() # Same as block size of CBC (that is 16 here) + rndStr = secrets.token_bytes(16) # Same as block size of CBC (that is 16 here) paddedLength = ((len(text) + 4 + 15) // 16) * 16 toEncode = ( struct.pack('>i', len(text)) + text + rndStr[: paddedLength - len(text) - 4] @@ -255,9 +254,9 @@ class CryptoManager(metaclass=singleton.Singleton): return not hash if hash[:8] == '{SHA256}': - return hashlib.sha3_256(value).hexdigest() == hash[8:] + return secrets.compare_digest(hashlib.sha3_256(value).hexdigest(), hash[8:]) else: # Old sha1 - return hash == str(hashlib.sha1(value).hexdigest()) # nosec: Old compatibility, not used anymore but need to be supported + return secrets.compare_digest(hash, str(hashlib.sha1(value).hexdigest())) # nosec: Old compatibility SHA1, not used anymore but need to be supported def uuid(self, obj: typing.Any = None) -> str: """ @@ -278,7 +277,7 @@ class CryptoManager(metaclass=singleton.Singleton): def randomString(self, length: int = 40, digits: bool = True) -> str: base = string.ascii_letters + (string.digits if digits else '') - return ''.join(random.SystemRandom().choices(base, k=length)) + return ''.join(secrets.choice(base) for _ in range(length)) def unique(self) -> str: return hashlib.sha3_256( diff --git a/server/src/uds/web/views/modern.py b/server/src/uds/web/views/modern.py index 44a451b86..114cfc077 100644 --- a/server/src/uds/web/views/modern.py +++ b/server/src/uds/web/views/modern.py @@ -32,6 +32,7 @@ import time import logging import hashlib import typing +import random import json from django.middleware import csrf @@ -54,6 +55,7 @@ from uds.web.util.authentication import checkLogin from uds.web.util.services import getServicesData from uds.web.util import configjs from uds.core import mfas +from uds import models @@ -127,8 +129,8 @@ def login( if loginResult.url: # Redirection return HttpResponseRedirect(loginResult.url) - if request.ip != '127.0.0.1': - time.sleep(2) # On failure, wait a bit if not localhost + if request.ip not in ('127.0.0.1', '::1'): # If not localhost, wait a bit + time.sleep(random.SystemRandom().randint(1600, 2400) / 1000) # On failure, wait a bit if not localhost (random wait) # If error is numeric, redirect... if loginResult.errid: return errors.errorView(request, loginResult.errid) @@ -179,7 +181,7 @@ def mfa(request: ExtendedHttpRequest) -> HttpResponse: return HttpResponseRedirect(reverse('page.index')) userHashValue: str = hashlib.sha3_256( - (request.user.name + (request.user.uuid or '') + mfaProvider.uuid).encode() + (request.user.name + (request.user.uuid or '') + mfaProvider.uuid + request.ip).encode() ).hexdigest() # Try to get cookie anc check it @@ -336,7 +338,7 @@ def update_transport_ticket(request: ExtendedHttpRequestWithUser, idTicket: str, return HttpResponse('{"status": "OK"}', status=200, content_type='application/json') except Exception as e: # fallback to error - pass + logger.warning('Error updating ticket: %s', e) # Invalid request return HttpResponse('{"status": "Invalid Request"}', status=400, content_type='application/json')