From ae4ce3a0a6af5e928ca50fbcad1b7201d7ced8a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Thu, 19 Dec 2024 08:15:27 +0100 Subject: [PATCH] fix: avoid using 0 as a solution This is a regression I've introduced in #3. Fixes #10 --- altcha/altcha.py | 2 +- tests/test_altcha.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/altcha/altcha.py b/altcha/altcha.py index 1214fab..4f34247 100644 --- a/altcha/altcha.py +++ b/altcha/altcha.py @@ -247,7 +247,7 @@ def create_challenge(options): options.salt or base64.b16encode(secrets.token_bytes(salt_length)).decode("utf-8").lower() ) - number = options.number or secrets.randbelow(max_number) + number = options.number or (secrets.randbelow(max_number - 1) + 1) salt_params = {} if "?" in salt: diff --git a/tests/test_altcha.py b/tests/test_altcha.py index c6db5dd..7cbcd3a 100644 --- a/tests/test_altcha.py +++ b/tests/test_altcha.py @@ -286,6 +286,35 @@ def test_hmac_hex(self): ).hexdigest() self.assertEqual(result, expected) + def test_verify_random(self): + for _i in range(1000): + secret = "xxxxxxxxxx" + challenge_options = ChallengeOptions( + hmac_key=secret, + max_number=100, + ) + challenge = create_challenge(challenge_options) + solution = solve_challenge( + challenge=challenge.challenge, + salt=challenge.salt, + algorithm=challenge.algorithm, + max_number=challenge.maxnumber, + start=0, + ) + response = base64.b64encode( + json.dumps( + { + "algorithm": challenge.algorithm, + "challenge": challenge.challenge, + "number": solution.number, + "salt": challenge.salt, + "signature": challenge.signature, + } + ).encode("utf-8") + ).decode("utf-8") + result = verify_solution(response, secret, check_expires=False) + self.assertTrue(result[0]) + if __name__ == "__main__": unittest.main()