Compare commits

...

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
6a3fb703e7 Add continue statements for both error cases in IP ban loading
Co-authored-by: frenck <195327+frenck@users.noreply.github.com>
2025-11-25 10:33:17 +00:00
copilot-swe-agent[bot]
d2dc752328 Initial plan 2025-11-25 10:30:05 +00:00
Franck Nijhof
9c5d2ecce6 Handle invalid IP addresses in ip_bans.yaml gracefully
When an invalid IP address entry exists in ip_bans.yaml (e.g., a typo
like "Eo128.199.160.243"), Home Assistant would crash with a ValueError
during startup, making the web UI completely unreachable.

This change catches ValueError exceptions when parsing IP addresses
from the ban file and logs an error message while skipping the invalid
entry. Valid IP bans continue to be loaded and enforced normally.

Fixes #157180

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 09:44:17 +00:00
2 changed files with 45 additions and 0 deletions

View File

@@ -233,6 +233,9 @@ class IpBanManager:
except vol.Invalid as err:
_LOGGER.error("Failed to load IP ban %s: %s", ip_info, err)
continue
except ValueError:
_LOGGER.error("Failed to load IP ban: invalid IP address %s", ip_ban)
continue
self.ip_bans_lookup = ip_bans_lookup

View File

@@ -113,6 +113,48 @@ async def test_access_from_banned_ip_with_partially_broken_yaml_file(
assert "Failed to load IP ban" in caplog.text
async def test_access_from_banned_ip_with_invalid_ip_entry(
hass: HomeAssistant,
aiohttp_client: ClientSessionGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test that invalid IP addresses in ban file are skipped gracefully.
An invalid IP entry (e.g., with typo like "Eo128.199.160.243") should
be logged as an error and skipped, allowing valid bans to still load.
"""
app = web.Application()
app[KEY_HASS] = hass
setup_bans(hass, app, 5)
set_real_ip = mock_real_ip(app)
data = {banned_ip: {"banned_at": "2016-11-16T19:20:03"} for banned_ip in BANNED_IPS}
# Add invalid IP entries that should be skipped
data["Eo128.199.160.243"] = {"banned_at": "2024-07-06T14:07:46"}
data["invalidip"] = {"banned_at": "2024-07-06T14:07:46"}
with patch(
"homeassistant.components.http.ban.load_yaml_config_file",
return_value=data,
):
client = await aiohttp_client(app)
# Valid banned IPs should still be blocked
for remote_addr in BANNED_IPS:
set_real_ip(remote_addr)
resp = await client.get("/")
assert resp.status == HTTPStatus.FORBIDDEN
# Non-banned IP should have access
set_real_ip("192.168.1.1")
resp = await client.get("/")
assert resp.status == HTTPStatus.NOT_FOUND
# Check that invalid IP entries were logged
assert "Failed to load IP ban" in caplog.text
assert "Eo128.199.160.243" in caplog.text
async def test_no_ip_bans_file(
hass: HomeAssistant, aiohttp_client: ClientSessionGenerator
) -> None: