mirror of https://github.com/searxng/searxng.git
[mod] limiter: add random token to the limiter URL
By adding a random component in the limiter URL a bot can no longer send a ping by request a static URL. Related: https://github.com/searxng/searxng/pull/2357#issuecomment-1518525094 Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
parent
dba569462d
commit
5226044c13
|
@ -14,6 +14,8 @@ Enable the plugin in ``settings.yml``:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import string
|
||||||
|
import random
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from searx import redisdb
|
from searx import redisdb
|
||||||
|
@ -54,6 +56,27 @@ def ping():
|
||||||
redis_client.set(secret_hash(ping_key), 1, ex=600)
|
redis_client.set(secret_hash(ping_key), 1, ex=600)
|
||||||
|
|
||||||
|
|
||||||
|
def get_token():
|
||||||
|
redis_client = redisdb.client()
|
||||||
|
if not redis_client:
|
||||||
|
# This function is also called when limiter is inactive / no redis DB
|
||||||
|
# (see render function in webapp.py)
|
||||||
|
return '12345678'
|
||||||
|
token = redis_client.get(TOKEN_KEY)
|
||||||
|
if token:
|
||||||
|
token = token.decode('UTF-8')
|
||||||
|
else:
|
||||||
|
token = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(8))
|
||||||
|
redis_client.set(TOKEN_KEY, token, ex=600)
|
||||||
|
return token
|
||||||
|
|
||||||
|
|
||||||
|
def token_is_valid(token):
|
||||||
|
valid = token == get_token()
|
||||||
|
logger.debug("token is valid --> %s", valid)
|
||||||
|
return valid
|
||||||
|
|
||||||
|
|
||||||
def is_accepted_request() -> bool:
|
def is_accepted_request() -> bool:
|
||||||
# pylint: disable=too-many-return-statements
|
# pylint: disable=too-many-return-statements
|
||||||
redis_client = redisdb.client()
|
redis_client = redisdb.client()
|
||||||
|
@ -83,7 +106,7 @@ def is_accepted_request() -> bool:
|
||||||
c_burst = incr_sliding_window(redis_client, 'IP limit, burst' + x_forwarded_for, 20)
|
c_burst = incr_sliding_window(redis_client, 'IP limit, burst' + x_forwarded_for, 20)
|
||||||
c_10min = incr_sliding_window(redis_client, 'IP limit, 10 minutes' + x_forwarded_for, 600)
|
c_10min = incr_sliding_window(redis_client, 'IP limit, 10 minutes' + x_forwarded_for, 600)
|
||||||
if c_burst > c_burst_max or c_10min > c_10min_max:
|
if c_burst > c_burst_max or c_10min > c_10min_max:
|
||||||
logger.debug("BLOCK %s: to many request", x_forwarded_for)
|
logger.debug("BLOCK %s: too many request", x_forwarded_for)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if len(request.headers.get('Accept-Language', '').strip()) == '':
|
if len(request.headers.get('Accept-Language', '').strip()) == '':
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/searxng.min.css') }}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/searxng.min.css') }}" type="text/css" media="screen" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if get_setting('server.limiter') %}
|
{% if get_setting('server.limiter') %}
|
||||||
<link rel="stylesheet" href="/limiter.css" type="text/css" media="screen" />
|
<link rel="stylesheet" href="{{ url_for('limiter_css', token=limiter_token) }}" type="text/css" media="screen" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% block styles %}{% endblock %}
|
{% block styles %}{% endblock %}
|
||||||
<!--[if gte IE 9]>-->
|
<!--[if gte IE 9]>-->
|
||||||
|
|
|
@ -416,6 +416,7 @@ def render(template_name: str, **kwargs):
|
||||||
kwargs['endpoint'] = 'results' if 'q' in kwargs else request.endpoint
|
kwargs['endpoint'] = 'results' if 'q' in kwargs else request.endpoint
|
||||||
kwargs['cookies'] = request.cookies
|
kwargs['cookies'] = request.cookies
|
||||||
kwargs['errors'] = request.errors
|
kwargs['errors'] = request.errors
|
||||||
|
kwargs['limiter_token'] = limiter.get_token()
|
||||||
|
|
||||||
# values from the preferences
|
# values from the preferences
|
||||||
kwargs['preferences'] = request.preferences
|
kwargs['preferences'] = request.preferences
|
||||||
|
@ -642,8 +643,9 @@ def health():
|
||||||
return Response('OK', mimetype='text/plain')
|
return Response('OK', mimetype='text/plain')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/limiter.css', methods=['GET', 'POST'])
|
@app.route('/limiter<token>.css', methods=['GET', 'POST'])
|
||||||
def limiter_css():
|
def limiter_css(token=None):
|
||||||
|
if limiter.token_is_valid(token):
|
||||||
limiter.ping()
|
limiter.ping()
|
||||||
return Response('', mimetype='text/css')
|
return Response('', mimetype='text/css')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue