mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Merge pull request #45186 from home-assistant/rc
This commit is contained in:
commit
b4268edd6a
@ -40,12 +40,19 @@ def setup_security_filter(app):
|
|||||||
@middleware
|
@middleware
|
||||||
async def security_filter_middleware(request, handler):
|
async def security_filter_middleware(request, handler):
|
||||||
"""Process request and block commonly known exploit attempts."""
|
"""Process request and block commonly known exploit attempts."""
|
||||||
if FILTERS.search(request.raw_path):
|
if FILTERS.search(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):
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Filtered a request with a potential harmful query string: %s",
|
||||||
|
request.raw_path,
|
||||||
|
)
|
||||||
|
raise HTTPBadRequest
|
||||||
|
|
||||||
return await handler(request)
|
return await handler(request)
|
||||||
|
|
||||||
app.middlewares.append(security_filter_middleware)
|
app.middlewares.append(security_filter_middleware)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Constants used by Home Assistant components."""
|
"""Constants used by Home Assistant components."""
|
||||||
MAJOR_VERSION = 2021
|
MAJOR_VERSION = 2021
|
||||||
MINOR_VERSION = 1
|
MINOR_VERSION = 1
|
||||||
PATCH_VERSION = "2"
|
PATCH_VERSION = "3"
|
||||||
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||||
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
__version__ = f"{__short_version__}.{PATCH_VERSION}"
|
||||||
REQUIRED_PYTHON_VER = (3, 7, 1)
|
REQUIRED_PYTHON_VER = (3, 7, 1)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
PyJWT==1.7.1
|
PyJWT==1.7.1
|
||||||
PyNaCl==1.3.0
|
PyNaCl==1.3.0
|
||||||
aiohttp==3.7.1
|
aiohttp==3.7.3
|
||||||
aiohttp_cors==0.7.0
|
aiohttp_cors==0.7.0
|
||||||
astral==1.10.1
|
astral==1.10.1
|
||||||
async_timeout==3.0.1
|
async_timeout==3.0.1
|
||||||
@ -29,7 +29,7 @@ ruamel.yaml==0.15.100
|
|||||||
sqlalchemy==1.3.20
|
sqlalchemy==1.3.20
|
||||||
voluptuous-serialize==2.4.0
|
voluptuous-serialize==2.4.0
|
||||||
voluptuous==0.12.1
|
voluptuous==0.12.1
|
||||||
yarl==1.4.2
|
yarl==1.6.3
|
||||||
zeroconf==0.28.8
|
zeroconf==0.28.8
|
||||||
|
|
||||||
pycryptodome>=3.6.6
|
pycryptodome>=3.6.6
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
-c homeassistant/package_constraints.txt
|
-c homeassistant/package_constraints.txt
|
||||||
|
|
||||||
# Home Assistant Core
|
# Home Assistant Core
|
||||||
aiohttp==3.7.1
|
aiohttp==3.7.3
|
||||||
astral==1.10.1
|
astral==1.10.1
|
||||||
async_timeout==3.0.1
|
async_timeout==3.0.1
|
||||||
attrs==19.3.0
|
attrs==19.3.0
|
||||||
@ -21,4 +21,4 @@ requests==2.25.0
|
|||||||
ruamel.yaml==0.15.100
|
ruamel.yaml==0.15.100
|
||||||
voluptuous==0.12.1
|
voluptuous==0.12.1
|
||||||
voluptuous-serialize==2.4.0
|
voluptuous-serialize==2.4.0
|
||||||
yarl==1.4.2
|
yarl==1.6.3
|
||||||
|
4
setup.py
4
setup.py
@ -32,7 +32,7 @@ PROJECT_URLS = {
|
|||||||
PACKAGES = find_packages(exclude=["tests", "tests.*"])
|
PACKAGES = find_packages(exclude=["tests", "tests.*"])
|
||||||
|
|
||||||
REQUIRES = [
|
REQUIRES = [
|
||||||
"aiohttp==3.7.1",
|
"aiohttp==3.7.3",
|
||||||
"astral==1.10.1",
|
"astral==1.10.1",
|
||||||
"async_timeout==3.0.1",
|
"async_timeout==3.0.1",
|
||||||
"attrs==19.3.0",
|
"attrs==19.3.0",
|
||||||
@ -53,7 +53,7 @@ REQUIRES = [
|
|||||||
"ruamel.yaml==0.15.100",
|
"ruamel.yaml==0.15.100",
|
||||||
"voluptuous==0.12.1",
|
"voluptuous==0.12.1",
|
||||||
"voluptuous-serialize==2.4.0",
|
"voluptuous-serialize==2.4.0",
|
||||||
"yarl==1.4.2",
|
"yarl==1.6.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIN_PY_VERSION = ".".join(map(str, hass_const.REQUIRED_PYTHON_VER))
|
MIN_PY_VERSION = ".".join(map(str, hass_const.REQUIRED_PYTHON_VER))
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Test security filter middleware."""
|
"""Test security filter middleware."""
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
import pytest
|
import pytest
|
||||||
|
import urllib3
|
||||||
|
|
||||||
from homeassistant.components.http.security_filter import setup_security_filter
|
from homeassistant.components.http.security_filter import setup_security_filter
|
||||||
|
|
||||||
@ -35,17 +36,26 @@ async def test_ok_requests(request_path, request_params, aiohttp_client):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"request_path,request_params",
|
"request_path,request_params,fail_on_query_string",
|
||||||
[
|
[
|
||||||
("/proc/self/environ", {}),
|
("/proc/self/environ", {}, False),
|
||||||
("/", {"test": "/test/../../api"}),
|
("/", {"test": "/test/../../api"}, True),
|
||||||
("/", {"test": "test/../../api"}),
|
("/", {"test": "test/../../api"}, True),
|
||||||
("/", {"sql": ";UNION SELECT (a, b"}),
|
("/", {"test": "/test/%2E%2E%2f%2E%2E%2fapi"}, True),
|
||||||
("/", {"sql": "concat(..."}),
|
("/", {"test": "test/%2E%2E%2f%2E%2E%2fapi"}, True),
|
||||||
("/", {"xss": "<script >"}),
|
("/test/%2E%2E%2f%2E%2E%2fapi", {}, False),
|
||||||
|
("/", {"sql": ";UNION SELECT (a, b"}, True),
|
||||||
|
("/", {"sql": "UNION%20SELECT%20%28a%2C%20b"}, True),
|
||||||
|
("/UNION%20SELECT%20%28a%2C%20b", {}, False),
|
||||||
|
("/", {"sql": "concat(..."}, True),
|
||||||
|
("/", {"xss": "<script >"}, True),
|
||||||
|
("/<script >", {"xss": ""}, False),
|
||||||
|
("/%3Cscript%3E", {}, False),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_bad_requests(request_path, request_params, aiohttp_client):
|
async def test_bad_requests(
|
||||||
|
request_path, request_params, fail_on_query_string, aiohttp_client, caplog, loop
|
||||||
|
):
|
||||||
"""Test request paths that should be filtered."""
|
"""Test request paths that should be filtered."""
|
||||||
app = web.Application()
|
app = web.Application()
|
||||||
app.router.add_get("/{all:.*}", mock_handler)
|
app.router.add_get("/{all:.*}", mock_handler)
|
||||||
@ -53,6 +63,26 @@ async def test_bad_requests(request_path, request_params, aiohttp_client):
|
|||||||
setup_security_filter(app)
|
setup_security_filter(app)
|
||||||
|
|
||||||
mock_api_client = await aiohttp_client(app)
|
mock_api_client = await aiohttp_client(app)
|
||||||
resp = await mock_api_client.get(request_path, params=request_params)
|
|
||||||
|
# Manual params handling
|
||||||
|
if request_params:
|
||||||
|
raw_params = "&".join(f"{val}={key}" for val, key in request_params.items())
|
||||||
|
man_params = f"?{raw_params}"
|
||||||
|
else:
|
||||||
|
man_params = ""
|
||||||
|
|
||||||
|
http = urllib3.PoolManager()
|
||||||
|
resp = await loop.run_in_executor(
|
||||||
|
None,
|
||||||
|
http.request,
|
||||||
|
"GET",
|
||||||
|
f"http://{mock_api_client.host}:{mock_api_client.port}/{request_path}{man_params}",
|
||||||
|
request_params,
|
||||||
|
)
|
||||||
|
|
||||||
assert resp.status == 400
|
assert resp.status == 400
|
||||||
|
|
||||||
|
message = "Filtered a potential harmful request to:"
|
||||||
|
if fail_on_query_string:
|
||||||
|
message = "Filtered a request with a potential harmful query string:"
|
||||||
|
assert message in caplog.text
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
This is just a text
|
@ -0,0 +1 @@
|
|||||||
|
I sing a song
|
Loading…
x
Reference in New Issue
Block a user