Do not process forwarded for headers for cloud requests (#54364)
This commit is contained in:
parent
a40deac714
commit
38a7bdbcf3
6 changed files with 34 additions and 5 deletions
|
@ -2,7 +2,7 @@
|
|||
"domain": "cloud",
|
||||
"name": "Home Assistant Cloud",
|
||||
"documentation": "https://www.home-assistant.io/integrations/cloud",
|
||||
"requirements": ["hass-nabucasa==0.44.0"],
|
||||
"requirements": ["hass-nabucasa==0.45.1"],
|
||||
"dependencies": ["http", "webhook"],
|
||||
"after_dependencies": ["google_assistant", "alexa"],
|
||||
"codeowners": ["@home-assistant/cloud"],
|
||||
|
|
|
@ -63,12 +63,19 @@ def async_setup_forwarded(
|
|||
an HTTP 400 status code is thrown.
|
||||
"""
|
||||
|
||||
try:
|
||||
from hass_nabucasa import remote # pylint: disable=import-outside-toplevel
|
||||
except ImportError:
|
||||
remote = None
|
||||
|
||||
@middleware
|
||||
async def forwarded_middleware(
|
||||
request: Request, handler: Callable[[Request], Awaitable[StreamResponse]]
|
||||
) -> StreamResponse:
|
||||
"""Process forwarded data by a reverse proxy."""
|
||||
overrides: dict[str, str] = {}
|
||||
# Skip requests from Remote UI
|
||||
if remote is not None and remote.is_cloud_request.get():
|
||||
return await handler(request)
|
||||
|
||||
# Handle X-Forwarded-For
|
||||
forwarded_for_headers: list[str] = request.headers.getall(X_FORWARDED_FOR, [])
|
||||
|
@ -120,6 +127,8 @@ def async_setup_forwarded(
|
|||
)
|
||||
raise HTTPBadRequest from err
|
||||
|
||||
overrides: dict[str, str] = {}
|
||||
|
||||
# Find the last trusted index in the X-Forwarded-For list
|
||||
forwarded_for_index = 0
|
||||
for forwarded_ip in forwarded_for:
|
||||
|
|
|
@ -16,7 +16,7 @@ cryptography==3.3.2
|
|||
defusedxml==0.7.1
|
||||
distro==1.5.0
|
||||
emoji==1.2.0
|
||||
hass-nabucasa==0.44.0
|
||||
hass-nabucasa==0.45.1
|
||||
home-assistant-frontend==20210809.0
|
||||
httpx==0.18.2
|
||||
ifaddr==0.1.7
|
||||
|
|
|
@ -753,7 +753,7 @@ habitipy==0.2.0
|
|||
hangups==0.4.14
|
||||
|
||||
# homeassistant.components.cloud
|
||||
hass-nabucasa==0.44.0
|
||||
hass-nabucasa==0.45.1
|
||||
|
||||
# homeassistant.components.splunk
|
||||
hass_splunk==0.1.1
|
||||
|
|
|
@ -431,7 +431,7 @@ habitipy==0.2.0
|
|||
hangups==0.4.14
|
||||
|
||||
# homeassistant.components.cloud
|
||||
hass-nabucasa==0.44.0
|
||||
hass-nabucasa==0.45.1
|
||||
|
||||
# homeassistant.components.tasmota
|
||||
hatasmota==0.2.20
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Test real forwarded middleware."""
|
||||
from ipaddress import ip_network
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from aiohttp import web
|
||||
from aiohttp.hdrs import X_FORWARDED_FOR, X_FORWARDED_HOST, X_FORWARDED_PROTO
|
||||
|
@ -441,3 +442,22 @@ async def test_x_forwarded_host_with_empty_header(aiohttp_client, caplog):
|
|||
|
||||
assert resp.status == 400
|
||||
assert "Empty value received in X-Forward-Host header" in caplog.text
|
||||
|
||||
|
||||
async def test_x_forwarded_cloud(aiohttp_client, caplog):
|
||||
"""Test that cloud requests are not processed."""
|
||||
app = web.Application()
|
||||
app.router.add_get("/", mock_handler)
|
||||
async_setup_forwarded(app, True, [ip_network("127.0.0.1")])
|
||||
|
||||
mock_api_client = await aiohttp_client(app)
|
||||
|
||||
with patch(
|
||||
"hass_nabucasa.remote.is_cloud_request", Mock(get=Mock(return_value=True))
|
||||
):
|
||||
resp = await mock_api_client.get(
|
||||
"/", headers={X_FORWARDED_FOR: "222.222.222.222", X_FORWARDED_HOST: ""}
|
||||
)
|
||||
|
||||
# This request would normally fail because it's invalid, now it works.
|
||||
assert resp.status == 200
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue