From 8a7ea79fb39d6661d9f348215499df4f977b1538 Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Tue, 28 Oct 2025 10:23:27 +0100 Subject: [PATCH] Extra XSS checking --- changedetectionio/html_tools.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/changedetectionio/html_tools.py b/changedetectionio/html_tools.py index 934fb5329..46c0d0f9a 100644 --- a/changedetectionio/html_tools.py +++ b/changedetectionio/html_tools.py @@ -24,10 +24,13 @@ class JSONNotFound(ValueError): @lru_cache(maxsize=10000) def is_safe_valid_url(test_url): - import os - import validators - from changedetectionio.jinja2_custom import render as jinja_render from changedetectionio import strtobool + from changedetectionio.jinja2_custom import render as jinja_render + from urllib.parse import urlparse, parse_qs + import os + import re + import validators + allow_file_access = strtobool(os.getenv('ALLOW_FILE_URI', 'false')) safe_protocol_regex = '^(http|https|ftp|file):' if allow_file_access else '^(http|https|ftp):' @@ -52,6 +55,11 @@ def is_safe_valid_url(test_url): logger.warning(f'URL "{test_url}" is not safe, aborting.') return False + # Check query parameters and fragment + if re.search(r'[<>]', test_url): + logger.warning(f'URL "{test_url}" contains suspicious characters') + return False + # If hosts that only contain alphanumerics are allowed ("localhost" for example) allow_simplehost = not strtobool(os.getenv('BLOCK_SIMPLEHOSTS', 'False')) try: