From ede7932a5769fc936fdc3bf150e200aaca817f65 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 4 Jun 2021 09:14:18 -0700 Subject: [PATCH] Protect our user agent (#51486) * Protect our user agent * Fix expected error --- homeassistant/helpers/aiohttp_client.py | 8 +++++++- tests/helpers/test_aiohttp_client.py | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index 0bb9a815c846..696f2d40cb8a 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -6,6 +6,7 @@ from collections.abc import Awaitable from contextlib import suppress from ssl import SSLContext import sys +from types import MappingProxyType from typing import Any, Callable, cast import aiohttp @@ -95,9 +96,14 @@ def _async_create_clientsession( """Create a new ClientSession with kwargs, i.e. for cookies.""" clientsession = aiohttp.ClientSession( connector=_async_get_connector(hass, verify_ssl), - headers={USER_AGENT: SERVER_SOFTWARE}, **kwargs, ) + # Prevent packages accidentally overriding our default headers + # It's important that we identify as Home Assistant + # If a package requires a different user agent, override it by passing a headers + # dictionary to the request method. + # pylint: disable=protected-access + clientsession._default_headers = MappingProxyType({USER_AGENT: SERVER_SOFTWARE}) # type: ignore clientsession.close = warn_use(clientsession.close, WARN_CLOSE_MSG) # type: ignore diff --git a/tests/helpers/test_aiohttp_client.py b/tests/helpers/test_aiohttp_client.py index e6f113c7699d..f68c7ba2181a 100644 --- a/tests/helpers/test_aiohttp_client.py +++ b/tests/helpers/test_aiohttp_client.py @@ -195,3 +195,14 @@ async def test_async_aiohttp_proxy_stream_client_err(aioclient_mock, camera_clie resp = await camera_client.get("/api/camera_proxy_stream/camera.config_test") assert resp.status == 502 + + +async def test_client_session_immutable_headers(hass): + """Test we can't mutate headers.""" + session = client.async_get_clientsession(hass) + + with pytest.raises(TypeError): + session.headers["user-agent"] = "bla" + + with pytest.raises(AttributeError): + session.headers.update({"user-agent": "bla"})