From 49bc982c697169c98b79698889fb9d26f6b3317f Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Thu, 7 Nov 2024 18:44:08 +0100 Subject: [PATCH] CVE-2024-51998 - file:/ path traversal access should not be allowed to access a file without ALLOW_FILE_URI set --- changedetectionio/processors/__init__.py | 4 ++-- changedetectionio/tests/test_security.py | 29 +++++++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/changedetectionio/processors/__init__.py b/changedetectionio/processors/__init__.py index fbe62937..2dcc9730 100644 --- a/changedetectionio/processors/__init__.py +++ b/changedetectionio/processors/__init__.py @@ -33,8 +33,8 @@ class difference_detection_processor(): url = self.watch.link - # Protect against file:// access, check the real "link" without any meta "source:" etc prepended. - if re.search(r'^file://', url, re.IGNORECASE): + # Protect against file://, file:/ access, check the real "link" without any meta "source:" etc prepended. + if re.search(r'^file:/', url.strip(), re.IGNORECASE): if not strtobool(os.getenv('ALLOW_FILE_URI', 'false')): raise Exception( "file:// type access is denied for security reasons." diff --git a/changedetectionio/tests/test_security.py b/changedetectionio/tests/test_security.py index af55efb2..5bb9e879 100644 --- a/changedetectionio/tests/test_security.py +++ b/changedetectionio/tests/test_security.py @@ -61,7 +61,7 @@ def test_bad_access(client, live_server, measure_memory_usage): assert b'Watch protocol is not permitted by SAFE_PROTOCOL_REGEX' in res.data -def test_file_access(client, live_server, measure_memory_usage): +def test_file_slashslash_access(client, live_server, measure_memory_usage): #live_server_setup(live_server) test_file_path = "/tmp/test-file.txt" @@ -88,6 +88,33 @@ def test_file_access(client, live_server, measure_memory_usage): # Default should be here assert b'file:// type access is denied for security reasons.' in res.data +def test_file_slash_access(client, live_server, measure_memory_usage): + #live_server_setup(live_server) + + test_file_path = "/tmp/test-file.txt" + + # file:// is permitted by default, but it will be caught by ALLOW_FILE_URI + client.post( + url_for("form_quick_watch_add"), + data={"url": f"file:/{test_file_path}", "tags": ''}, + follow_redirects=True + ) + wait_for_all_checks(client) + res = client.get(url_for("index")) + + # If it is enabled at test time + if strtobool(os.getenv('ALLOW_FILE_URI', 'false')): + res = client.get( + url_for("preview_page", uuid="first"), + follow_redirects=True + ) + + # Should see something (this file added by run_basic_tests.sh) + assert b"Hello world" in res.data + else: + # Default should be here + assert b'file:// type access is denied for security reasons.' in res.data + def test_xss(client, live_server, measure_memory_usage): #live_server_setup(live_server) from changedetectionio.notification import (