From d7848702097ca6a3e8630ca6d46210abf7314673 Mon Sep 17 00:00:00 2001 From: Alexandre Flament Date: Tue, 28 Dec 2021 08:36:31 +0100 Subject: [PATCH 1/3] [fix] use hmac.compare_digest instead of == see https://docs.python.org/3/library/hmac.html#hmac.HMAC.hexdigest --- searx/webapp.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/searx/webapp.py b/searx/webapp.py index a7812f181..788e0d24f 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -1067,8 +1067,9 @@ def image_proxy(): if not url: return '', 400 - h = new_hmac(settings['server']['secret_key'], url.encode()) - if h != request.args.get('h'): + h_url = new_hmac(settings['server']['secret_key'], url.encode()) + h_args = request.args.get('h') + if len(h_url) != len(h_args) or not hmac.compare_digest(h_url, h_args): return '', 400 maximum_size = 5 * 1024 * 1024 From 7d4834ac4dd708b87187caff8eb59e783e8c2111 Mon Sep 17 00:00:00 2001 From: Alexandre Flament Date: Tue, 28 Dec 2021 10:14:38 +0100 Subject: [PATCH 2/3] [mod] webutils.py: remove dead code secret_key can't be bytes (see settings_default.py) --- searx/webutils.py | 9 +-------- tests/unit/test_webutils.py | 16 +++++++++------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/searx/webutils.py b/searx/webutils.py index 737e5a82f..11a101806 100644 --- a/searx/webutils.py +++ b/searx/webutils.py @@ -77,14 +77,7 @@ def get_result_templates(templates_path): def new_hmac(secret_key, url): - try: - secret_key_bytes = bytes(secret_key, 'utf-8') - except TypeError as err: - if isinstance(secret_key, bytes): - secret_key_bytes = secret_key - else: - raise err - return hmac.new(secret_key_bytes, url, hashlib.sha256).hexdigest() + return hmac.new(secret_key.encode(), url, hashlib.sha256).hexdigest() def prettify_url(url, max_length=74): diff --git a/tests/unit/test_webutils.py b/tests/unit/test_webutils.py index 2b7c6fe5a..31a0f86ce 100644 --- a/tests/unit/test_webutils.py +++ b/tests/unit/test_webutils.py @@ -78,10 +78,12 @@ class TestUnicodeWriter(SearxTestCase): class TestNewHmac(SearxTestCase): def test_bytes(self): - for secret_key in ['secret', b'secret', 1]: - if secret_key == 1: - with self.assertRaises(TypeError): - webutils.new_hmac(secret_key, b'http://example.com') - continue - res = webutils.new_hmac(secret_key, b'http://example.com') - self.assertEqual(res, '23e2baa2404012a5cc8e4a18b4aabf0dde4cb9b56f679ddc0fd6d7c24339d819') + data = b'http://example.com' + with self.assertRaises(AttributeError): + webutils.new_hmac(b'secret', data) + + with self.assertRaises(AttributeError): + webutils.new_hmac(1, data) + + res = webutils.new_hmac('secret', data) + self.assertEqual(res, '23e2baa2404012a5cc8e4a18b4aabf0dde4cb9b56f679ddc0fd6d7c24339d819') From 8f3a7feb47a84344a190ce83e629afde1181f6ae Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Tue, 28 Dec 2021 13:44:28 +0100 Subject: [PATCH 3/3] [mod] implement is_hmac_of() in webutils / close to new_hmac() Signed-off-by: Markus Heiser , Alexandre Flament --- searx/webapp.py | 5 ++--- searx/webutils.py | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/searx/webapp.py b/searx/webapp.py index 788e0d24f..a2aa84d9d 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -71,6 +71,7 @@ from searx.webutils import ( get_themes, prettify_url, new_hmac, + is_hmac_of, is_flask_run_cmdline, ) from searx.webadapter import ( @@ -1067,9 +1068,7 @@ def image_proxy(): if not url: return '', 400 - h_url = new_hmac(settings['server']['secret_key'], url.encode()) - h_args = request.args.get('h') - if len(h_url) != len(h_args) or not hmac.compare_digest(h_url, h_args): + if not is_hmac_of(settings['server']['secret_key'], url.encode(), request.args.get('h', '')): return '', 400 maximum_size = 5 * 1024 * 1024 diff --git a/searx/webutils.py b/searx/webutils.py index 11a101806..068582858 100644 --- a/searx/webutils.py +++ b/searx/webutils.py @@ -80,6 +80,11 @@ def new_hmac(secret_key, url): return hmac.new(secret_key.encode(), url, hashlib.sha256).hexdigest() +def is_hmac_of(secret_key, value, hmac_to_check): + hmac_of_value = new_hmac(secret_key, value) + return len(hmac_of_value) == len(hmac_to_check) and hmac.compare_digest(hmac_of_value, hmac_to_check) + + def prettify_url(url, max_length=74): if len(url) > max_length: chunk_len = int(max_length / 2 + 1)