From 02f78b884d883a7ca14e5d5d3648e609ee33585a Mon Sep 17 00:00:00 2001 From: Joshua Date: Sun, 20 Sep 2026 20:05:49 -0400 Subject: [PATCH] Drop the unnecessary X-Frame-Options runbook step --- README.md | 58 ++++++++++-------------------------------- tests/test_frontend.py | 4 ++- 2 files changed, 16 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 884ba92..7c59ffe 100644 --- a/README.md +++ b/README.md @@ -161,57 +161,25 @@ Run these steps in order to display the NestQuest panel on a TouchHub wall device. The panel is an HA Lovelace dashboard, so the kiosk browser is simply a Home Assistant client. -1. **Allow the panel to be framed.** The NestQuest Lovelace panel card - embeds a Home Assistant iframe, which Home Assistant blocks by default. - Add the following to `configuration.yaml` and save it: - - ```yaml - http: - use_x_frame_options: false - ``` - -2. **Restart Home Assistant.** Use *Settings → System → Restart* and pick - **Restart Home Assistant** (a full restart, not a YAML reload) — the - `http:` setting is only applied at startup. - -3. **Create a dedicated kiosk user.** In *Settings → People → Users*, add - a new user for the wall device. Make it **non-admin**, and do **not** - add it to the NestQuest admin allowlist. This is the account the panel +1. **Create a dedicated kiosk user.** In *Settings → People → Users*, add + a new user for the wall device. Make it **non-admin**, and ensure it is + not in the NestQuest admin allowlist. This is the account the panel runs as, and it should have no authority beyond viewing the dashboard. -4. **Build a dashboard with only the NestQuest panel card.** Create a new - Lovelace dashboard that contains nothing but the NestQuest panel card. - Keep the surface minimal — no other cards, no admin controls. +2. **Build a dashboard with only the NestQuest panel card.** Create a new + Lovelace dashboard that contains only the NestQuest panel card. Keep + the surface minimal — no other cards, no admin controls. -5. **Point TouchHub at it.** In the TouchHub launcher, add the **Home +3. **Point TouchHub at it.** In the TouchHub launcher, add the **Home Assistant Lovelace** app to the dock and paste the dashboard URL from - step 4. TouchHub loads that URL in its kiosk browser. + step 2. -6. **Log the kiosk session in.** Sign in on the device as the dedicated - kiosk user from step 3, and leave that session logged in. +4. **Log the kiosk session in.** Sign in on the device as the dedicated + kiosk user from step 1, and leave that session logged in. -### The clickjacking trade-off - -`use_x_frame_options: false` removes the `X-Frame-Options` response -header, which is what stops Home Assistant from being embedded in a frame -on another site. Disabling it is what lets the panel card iframe Home -Assistant — but it also lets **any** page frame Home Assistant, so a -malicious site could render the HA UI invisibly and trick a logged-in -user into clicking controls they did not mean to click. That is -clickjacking. - -This is an accepted, scoped risk for a wall display, and it is contained -by how the kiosk account and dashboard are set up. Two mitigations: - -- The kiosk user is non-admin and is **not in the NestQuest admin - allowlist**, so even a hijacked click cannot reach admin-only - operations or other parts of Home Assistant. -- The dashboard **contains only the NestQuest panel card**, so there are - no unrelated controls on screen for a clickjacking overlay to weaponise. - -A third, optional hardening is to keep the kiosk browser on a trusted -device and network, and to leave the kiosk session logged in only on that -device. +TouchHub loads the dashboard URL directly. The NestQuest cards are normal +Lovelace cards, not an iframe, so no Home Assistant framing setting is +needed. ## Developer Setup and Testing diff --git a/tests/test_frontend.py b/tests/test_frontend.py index 27bb57d..b8acba3 100644 --- a/tests/test_frontend.py +++ b/tests/test_frontend.py @@ -169,7 +169,9 @@ def test_readme_documents_the_touchhub_setup_runbook() -> None: readme = " ".join( (REPO_ROOT / "README.md").read_text(encoding="utf-8").split() ) - for required in ("use_x_frame_options", "TouchHub", "kiosk", "clickjacking"): + for required in ("TouchHub", "kiosk"): assert required in readme, required assert "not in the NestQuest admin allowlist" in readme assert "contains only the NestQuest panel card" in readme + assert "use_x_frame_options" not in readme + assert "clickjacking" not in readme