.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.botdetection.http_sec_fetch Namespace Reference

Functions

bool is_browser_supported (str user_agent)
werkzeug.Response|None filter_request (IPv4Network|IPv6Network network, flask.Request request, config.Config cfg)

Detailed Description

Method ``http_sec_fetch``
-------------------------

The ``http_sec_fetch`` method protect resources from web attacks with `Fetch
Metadata`_.  A request is filtered out in case of:

- http header Sec-Fetch-Mode_ is invalid
- http header Sec-Fetch-Dest_ is invalid

.. _Fetch Metadata:
   https://developer.mozilla.org/en-US/docs/Glossary/Fetch_metadata_request_header

.. _Sec-Fetch-Dest:
   https://developer.mozilla.org/en-US/docs/Web/API/Request/destination

.. _Sec-Fetch-Mode:
   https://developer.mozilla.org/en-US/docs/Web/API/Request/mode

Function Documentation

◆ filter_request()

werkzeug.Response | None searx.botdetection.http_sec_fetch.filter_request ( IPv4Network | IPv6Network network,
flask.Request request,
config.Config cfg )

Definition at line 77 of file http_sec_fetch.py.

81) -> werkzeug.Response | None:
82
83 if not request.is_secure:
84 logger.warning(
85 "Sec-Fetch cannot be verified for non-secure requests (HTTP headers are not set/sent by the client)."
86 )
87 return None
88
89 # Only check Sec-Fetch headers for supported browsers
90 user_agent = request.headers.get('User-Agent', '')
91 if is_browser_supported(user_agent):
92 val = request.headers.get("Sec-Fetch-Mode", "")
93 if val not in ('navigate', 'cors'):
94 logger.debug("invalid Sec-Fetch-Mode '%s'", val)
95 return flask.redirect(flask.url_for('index'), code=302)
96
97 val = request.headers.get("Sec-Fetch-Site", "")
98 if val not in ('same-origin', 'same-site', 'none'):
99 logger.debug("invalid Sec-Fetch-Site '%s'", val)
100 flask.redirect(flask.url_for('index'), code=302)
101
102 val = request.headers.get("Sec-Fetch-Dest", "")
103 if val not in ('document', 'empty'):
104 logger.debug("invalid Sec-Fetch-Dest '%s'", val)
105 flask.redirect(flask.url_for('index'), code=302)
106
107 return None

References is_browser_supported().

Here is the call graph for this function:

◆ is_browser_supported()

bool searx.botdetection.http_sec_fetch.is_browser_supported ( str user_agent)
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)

Definition at line 39 of file http_sec_fetch.py.

39def is_browser_supported(user_agent: str) -> bool:
40 """Check if the browser supports Sec-Fetch headers.
41
42 https://caniuse.com/mdn-http_headers_sec-fetch-dest
43 https://caniuse.com/mdn-http_headers_sec-fetch-mode
44 https://caniuse.com/mdn-http_headers_sec-fetch-site
45
46 Supported browsers:
47 - Chrome >= 80
48 - Firefox >= 90
49 - Safari >= 16.4
50 - Edge (mirrors Chrome)
51 - Opera (mirrors Chrome)
52 """
53 user_agent = user_agent.lower()
54
55 # Chrome/Chromium/Edge/Opera
56 chrome_match = re.search(r'chrome/(\d+)', user_agent)
57 if chrome_match:
58 version = int(chrome_match.group(1))
59 return version >= 80
60
61 # Firefox
62 firefox_match = re.search(r'firefox/(\d+)', user_agent)
63 if firefox_match:
64 version = int(firefox_match.group(1))
65 return version >= 90
66
67 # Safari
68 safari_match = re.search(r'version/(\d+)\.(\d+)', user_agent)
69 if safari_match:
70 major = int(safari_match.group(1))
71 minor = int(safari_match.group(2))
72 return major > 16 or (major == 16 and minor >= 4)
73
74 return False
75
76

Referenced by filter_request().

Here is the caller graph for this function: