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 GitHub
parent 8321443193
commit 95ed6fbc08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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,
) )