From a167332518a0c7bb37c59d3a5b35fc9021557926 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 8 Feb 2026 07:14:20 -0600 Subject: [PATCH] Fix password_hash type and add HA add-on regression test Initialize password_hash as b"" (bytes) to match password_hash() return type, preventing TypeError in hmac.compare_digest when HA add-on auth is enabled without a password. --- esphome/dashboard/settings.py | 4 ++-- tests/dashboard/test_settings.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/esphome/dashboard/settings.py b/esphome/dashboard/settings.py index 5baa03d02d7..aa994ae4877 100644 --- a/esphome/dashboard/settings.py +++ b/esphome/dashboard/settings.py @@ -32,7 +32,7 @@ class DashboardSettings: def __init__(self) -> None: """Initialize the dashboard settings.""" self.config_dir: Path = None - self.password_hash: str = "" + self.password_hash: bytes = b"" self.username: str = "" self.using_password: bool = False self.on_ha_addon: bool = False @@ -84,7 +84,7 @@ class DashboardSettings: def check_password(self, username: str, password: str) -> bool: if not self.using_auth: return True - # Compare both in constant running time (to prevent timing attacks) + # Compare in constant running time (to prevent timing attacks) username_matches = hmac.compare_digest(username, self.username) password_matches = hmac.compare_digest( self.password_hash, password_hash(password) diff --git a/tests/dashboard/test_settings.py b/tests/dashboard/test_settings.py index 32e581083a4..a7594e42222 100644 --- a/tests/dashboard/test_settings.py +++ b/tests/dashboard/test_settings.py @@ -260,3 +260,18 @@ def test_check_password_both_wrong(auth_settings: DashboardSettings) -> None: def test_check_password_no_auth(dashboard_settings: DashboardSettings) -> None: """Test check_password returns True when auth is not configured.""" assert dashboard_settings.check_password("anyone", "anything") is True + + +def test_check_password_ha_addon_no_password( + dashboard_settings: DashboardSettings, +) -> None: + """Test check_password doesn't crash in HA add-on mode without a password. + + In HA add-on mode, using_ha_addon_auth can be True while using_password + is False, leaving password_hash as b"". This must not raise TypeError + in hmac.compare_digest. + """ + dashboard_settings.on_ha_addon = True + dashboard_settings.using_password = False + # password_hash stays as default b"" + assert dashboard_settings.check_password("anyone", "anything") is False