summaryrefslogtreecommitdiff
path: root/searx/botdetection/http_sec_fetch.py
diff options
context:
space:
mode:
authorÉmilien (perso) <4016501+unixfox@users.noreply.github.com>2025-05-04 08:12:25 +0000
committerGitHub <noreply@github.com>2025-05-04 10:12:25 +0200
commit19b116f1d7aaea2ab2b00868003e9dd852eabbe0 (patch)
tree6025fe6ed18e04a25be23aad24130288df623216 /searx/botdetection/http_sec_fetch.py
parentfe08bb1d909cb6cef57ce91211c2cbed63300c9e (diff)
fix: check if the browser supports Sec-Fetch headers (#4696)
Diffstat (limited to 'searx/botdetection/http_sec_fetch.py')
-rw-r--r--searx/botdetection/http_sec_fetch.py70
1 files changed, 56 insertions, 14 deletions
diff --git a/searx/botdetection/http_sec_fetch.py b/searx/botdetection/http_sec_fetch.py
index 9791e74e1..536fbbd3f 100644
--- a/searx/botdetection/http_sec_fetch.py
+++ b/searx/botdetection/http_sec_fetch.py
@@ -28,6 +28,7 @@ from ipaddress import (
IPv6Network,
)
+import re
import flask
import werkzeug
@@ -37,25 +38,66 @@ from . import config
from ._helpers import logger
+def is_browser_supported(user_agent: str) -> bool:
+ """Check if the browser supports Sec-Fetch headers.
+
+ https://caniuse.com/mdn-http_headers_sec-fetch-dest
+ https://caniuse.com/mdn-http_headers_sec-fetch-mode
+ https://caniuse.com/mdn-http_headers_sec-fetch-site
+
+ Supported browsers:
+ - Chrome >= 80
+ - Firefox >= 90
+ - Safari >= 16.4
+ - Edge (mirrors Chrome)
+ - Opera (mirrors Chrome)
+ """
+ user_agent = user_agent.lower()
+
+ # Chrome/Chromium/Edge/Opera
+ chrome_match = re.search(r'chrome/(\d+)', user_agent)
+ if chrome_match:
+ version = int(chrome_match.group(1))
+ return version >= 80
+
+ # Firefox
+ firefox_match = re.search(r'firefox/(\d+)', user_agent)
+ if firefox_match:
+ version = int(firefox_match.group(1))
+ return version >= 90
+
+ # Safari
+ safari_match = re.search(r'version/(\d+)\.(\d+)', user_agent)
+ if safari_match:
+ major = int(safari_match.group(1))
+ minor = int(safari_match.group(2))
+ return major > 16 or (major == 16 and minor >= 4)
+
+ return False
+
+
def filter_request(
network: IPv4Network | IPv6Network,
request: SXNG_Request,
cfg: config.Config,
) -> werkzeug.Response | None:
- val = request.headers.get("Sec-Fetch-Mode", "")
- if val != "navigate":
- logger.debug("invalid Sec-Fetch-Mode '%s'", val)
- return flask.redirect(flask.url_for('index'), code=302)
-
- val = request.headers.get("Sec-Fetch-Site", "")
- if val not in ('same-origin', 'same-site', 'none'):
- logger.debug("invalid Sec-Fetch-Site '%s'", val)
- flask.redirect(flask.url_for('index'), code=302)
-
- val = request.headers.get("Sec-Fetch-Dest", "")
- if val != "document":
- logger.debug("invalid Sec-Fetch-Dest '%s'", val)
- flask.redirect(flask.url_for('index'), code=302)
+ # Only check Sec-Fetch headers for supported browsers
+ user_agent = request.headers.get('User-Agent', '')
+ if is_browser_supported(user_agent):
+ val = request.headers.get("Sec-Fetch-Mode", "")
+ if val != "navigate":
+ logger.debug("invalid Sec-Fetch-Mode '%s'", val)
+ return flask.redirect(flask.url_for('index'), code=302)
+
+ val = request.headers.get("Sec-Fetch-Site", "")
+ if val not in ('same-origin', 'same-site', 'none'):
+ logger.debug("invalid Sec-Fetch-Site '%s'", val)
+ flask.redirect(flask.url_for('index'), code=302)
+
+ val = request.headers.get("Sec-Fetch-Dest", "")
+ if val != "document":
+ logger.debug("invalid Sec-Fetch-Dest '%s'", val)
+ flask.redirect(flask.url_for('index'), code=302)
return None