Small improvements to middleware filter (#88921)

Small improvements middleware filter
This commit is contained in:
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 logging
import re import re
from typing import Final from typing import Final
from urllib.parse import unquote
from aiohttp.web import Application, HTTPBadRequest, Request, StreamResponse, middleware from aiohttp.web import Application, HTTPBadRequest, Request, StreamResponse, middleware
@ -39,18 +40,24 @@ FILTERS: Final = re.compile(
def setup_security_filter(app: Application) -> None: def setup_security_filter(app: Application) -> None:
"""Create security filter middleware for the app.""" """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 @middleware
async def security_filter_middleware( async def security_filter_middleware(
request: Request, handler: Callable[[Request], Awaitable[StreamResponse]] request: Request, handler: Callable[[Request], Awaitable[StreamResponse]]
) -> StreamResponse: ) -> StreamResponse:
"""Process request and tblock commonly known exploit attempts.""" """Process request and block commonly known exploit attempts."""
if FILTERS.search(request.path): if FILTERS.search(_recursive_unquote(request.path)):
_LOGGER.warning( _LOGGER.warning(
"Filtered a potential harmful request to: %s", request.raw_path "Filtered a potential harmful request to: %s", request.raw_path
) )
raise HTTPBadRequest raise HTTPBadRequest
if FILTERS.search(request.query_string): if FILTERS.search(_recursive_unquote(request.query_string)):
_LOGGER.warning( _LOGGER.warning(
"Filtered a request with a potential harmful query string: %s", "Filtered a request with a potential harmful query string: %s",
request.raw_path, request.raw_path,

View File

@ -49,7 +49,17 @@ async def test_ok_requests(
("/", {"test": "test/../../api"}, True), ("/", {"test": "test/../../api"}, True),
("/", {"test": "/test/%2E%2E%2f%2E%2E%2fapi"}, True), ("/", {"test": "/test/%2E%2E%2f%2E%2E%2fapi"}, 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/%2E%2E%2f%2E%2E%2fapi", {}, False),
("/test/%2525252E%2525252E%2525252f%2525252E%2525252E/api", {}, False),
("/", {"sql": ";UNION SELECT (a, b"}, True), ("/", {"sql": ";UNION SELECT (a, b"}, True),
("/", {"sql": "UNION%20SELECT%20%28a%2C%20b"}, True), ("/", {"sql": "UNION%20SELECT%20%28a%2C%20b"}, True),
("/UNION%20SELECT%20%28a%2C%20b", {}, False), ("/UNION%20SELECT%20%28a%2C%20b", {}, False),
@ -87,7 +97,7 @@ async def test_bad_requests(
None, None,
http.request, http.request,
"GET", "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, request_params,
) )