summaryrefslogtreecommitdiff
path: root/searx/botdetection/link_token.py
diff options
context:
space:
mode:
authorMarkus Heiser <markus.heiser@darmarit.de>2023-06-01 15:41:48 +0200
committerMarkus Heiser <markus.heiser@darmarit.de>2023-06-01 15:51:14 +0200
commit281e36f4b7848374535d5e953050ae73423191ca (patch)
treef7bda906459c8e796ec688a0007191f3c3609d63 /searx/botdetection/link_token.py
parent38431d2e142b7da6a9b48aad203f02a2eff7e6fd (diff)
downloadsearxng-281e36f4b7848374535d5e953050ae73423191ca.tar.gz
searxng-281e36f4b7848374535d5e953050ae73423191ca.zip
[fix] limiter: replace real_ip by IPv4/v6 network
Closes: https://github.com/searxng/searxng/issues/2477 Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Diffstat (limited to 'searx/botdetection/link_token.py')
-rw-r--r--searx/botdetection/link_token.py54
1 files changed, 32 insertions, 22 deletions
diff --git a/searx/botdetection/link_token.py b/searx/botdetection/link_token.py
index a83214a33..11a6a56b5 100644
--- a/searx/botdetection/link_token.py
+++ b/searx/botdetection/link_token.py
@@ -6,7 +6,7 @@ Method ``link_token``
The ``link_token`` method evaluates a request as :py:obj:`suspicious
<is_suspicious>` if the URL ``/client<token>.css`` is not requested by the
-client. By adding a random component (the token) in the URL a bot can not send
+client. By adding a random component (the token) in the URL, a bot can not send
a ping by request a static URL.
.. note::
@@ -35,6 +35,11 @@ And in the HTML template from flask a stylesheet link is needed (the value of
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
"""
+from __future__ import annotations
+from ipaddress import (
+ IPv4Network,
+ IPv6Network,
+)
import string
import random
@@ -43,7 +48,11 @@ import flask
from searx import logger
from searx import redisdb
from searx.redislib import secret_hash
-from ._helpers import get_real_ip
+
+from ._helpers import (
+ get_network,
+ get_real_ip,
+)
TOKEN_LIVE_TIME = 600
"""Livetime (sec) of limiter's CSS token."""
@@ -60,29 +69,26 @@ TOKEN_KEY = 'SearXNG_limiter.token'
logger = logger.getChild('botdetection.link_token')
-def is_suspicious(request: flask.Request, renew: bool = False):
- """Checks if there is a valid ping for this request, if not this request is
- rated as *suspicious*. If a valid ping exists and argument ``renew`` is
- ``True`` the expire time of this ping is reset to :py:obj:`PING_LIVE_TIME`.
+def is_suspicious(network: IPv4Network | IPv6Network, request: flask.Request, renew: bool = False):
+ """Checks whether a valid ping is exists for this (client) network, if not
+ this request is rated as *suspicious*. If a valid ping exists and argument
+ ``renew`` is ``True`` the expire time of this ping is reset to
+ :py:obj:`PING_LIVE_TIME`.
"""
redis_client = redisdb.client()
if not redis_client:
return False
- ping_key = get_ping_key(request)
+ ping_key = get_ping_key(network, request)
if not redis_client.get(ping_key):
- logger.warning(
- "missing ping (IP: %s) / request: %s",
- get_real_ip(request),
- ping_key,
- )
+ logger.warning("missing ping (IP: %s) / request: %s", network.compressed, ping_key)
return True
if renew:
redis_client.set(ping_key, 1, ex=PING_LIVE_TIME)
- logger.debug("found ping for client request: %s", ping_key)
+ logger.debug("found ping for (client) network %s -> %s", network.compressed, ping_key)
return False
@@ -92,27 +98,31 @@ def ping(request: flask.Request, token: str):
The expire time of this ping-key is :py:obj:`PING_LIVE_TIME`.
"""
+ from . import limiter # pylint: disable=import-outside-toplevel, cyclic-import
+
redis_client = redisdb.client()
if not redis_client:
return
if not token_is_valid(token):
return
- ping_key = get_ping_key(request)
- logger.debug("store ping for: %s", ping_key)
- redis_client.set(ping_key, 1, ex=PING_LIVE_TIME)
+ cfg = limiter.get_cfg()
+ real_ip = get_real_ip(request)
+ network = get_network(real_ip, cfg)
-def get_ping_key(request: flask.Request):
- """Generates a hashed key that fits (more or less) to a client (request).
- At least X-Forwarded-For_ is needed to be able to assign the request to an
- IP.
+ ping_key = get_ping_key(network, request)
+ logger.debug("store ping_key for (client) network %s (IP %s) -> %s", network.compressed, real_ip, ping_key)
+ redis_client.set(ping_key, 1, ex=PING_LIVE_TIME)
- """
+
+def get_ping_key(network: IPv4Network | IPv6Network, request: flask.Request) -> str:
+ """Generates a hashed key that fits (more or less) to a *WEB-browser
+ session* in a network."""
return (
PING_KEY
+ "["
+ secret_hash(
- get_real_ip(request) + request.headers.get('Accept-Language', '') + request.headers.get('User-Agent', '')
+ network.compressed + request.headers.get('Accept-Language', '') + request.headers.get('User-Agent', '')
)
+ "]"
)