Small improvements to middleware filter (#88921)

Small improvements middleware filter
pull/88979/head
Franck Nijhof 2023-02-28 18:07:17 +01:00 committed by Paulus Schoutsen
parent 2238a3f201
commit 04cedab8d4
2 changed files with 21 additions and 4 deletions

View File

@ -5,6 +5,7 @@ from collections.abc import Awaitable, Callable
import logging
import re
from typing import Final
from urllib.parse import unquote
from aiohttp.web import Application, HTTPBadRequest, Request, StreamResponse, middleware
@ -39,18 +40,24 @@ FILTERS: Final = re.compile(
def setup_security_filter(app: Application) -> None:
"""Create security filter middleware for the app."""
def _recursive_unquote(value: str) -> str:
"""Handle values that are encoded multiple times."""
if (unquoted := unquote(value)) != value:
unquoted = _recursive_unquote(unquoted)
return unquoted
@middleware
async def security_filter_middleware(
request: Request, handler: Callable[[Request], Awaitable[StreamResponse]]
) -> StreamResponse:
"""Process request and tblock commonly known exploit attempts."""
if FILTERS.search(request.path):
"""Process request and block commonly known exploit attempts."""
if FILTERS.search(_recursive_unquote(request.path)):
_LOGGER.warning(
"Filtered a potential harmful request to: %s", request.raw_path
)
raise HTTPBadRequest
if FILTERS.search(request.query_string):
if FILTERS.search(_recursive_unquote(request.query_string)):
_LOGGER.warning(
"Filtered a request with a potential harmful query string: %s",
request.raw_path,

View File

@ -49,7 +49,17 @@ async def test_ok_requests(
("/", {"test": "test/../../api"}, True),
("/", {"test": "/test/%2E%2E%2f%2E%2E%2fapi"}, True),
("/", {"test": "test/%2E%2E%2f%2E%2E%2fapi"}, True),
("/", {"test": "test/%252E%252E/api"}, True),
("/", {"test": "test/%252E%252E%2fapi"}, True),
(
"/",
{"test": "test/%2525252E%2525252E%2525252f%2525252E%2525252E%2525252fapi"},
True,
),
("/test/.%252E/api", {}, False),
("/test/%252E%252E/api", {}, False),
("/test/%2E%2E%2f%2E%2E%2fapi", {}, False),
("/test/%2525252E%2525252E%2525252f%2525252E%2525252E/api", {}, False),
("/", {"sql": ";UNION SELECT (a, b"}, True),
("/", {"sql": "UNION%20SELECT%20%28a%2C%20b"}, True),
("/UNION%20SELECT%20%28a%2C%20b", {}, False),
@ -87,7 +97,7 @@ async def test_bad_requests(
None,
http.request,
"GET",
f"http://{mock_api_client.host}:{mock_api_client.port}/{request_path}{man_params}",
f"http://{mock_api_client.host}:{mock_api_client.port}{request_path}{man_params}",
request_params,
)