Home AssistantHome AssistantContributors
On this page

Home Assistant publishes an advisory for every valid vulnerability that meets the criteria of the security policy. This page groups them by kind, says in one sentence what went wrong, and names the lesson. Each advisory links to the full details on GitHub, and each lesson links to the guide that covers it.

The list itself, with severity, CVE, discoverer, and the version with the fix, lives on the security page. That list is the official one. This page only helps you learn from it.

The same few mistakes keep coming back. Read the group that matches the code you work on.

Cross-site scripting

Data that reached the frontend was rendered as HTML, so a crafted name or message could run code in the browser of whoever looked at it.

Date What went wrong Lesson
2026‑03‑27 A device name with HTML in it ran as code in the tooltip of the map card. Names are data, never markup. Let Lit render them, or set textContent. See frontend.
2026‑03‑27 An entity name ran as code in the tooltip of the history graph card. The same mistake in another card: check every place that builds an HTML string. See frontend.
2025‑10‑14 An entity name ran as code in a graph tooltip of the energy dashboard. The name could come from the cloud service of the integration, not only from a user. Any name can come from outside, including the default name an integration sets. See frontend.
2017‑10‑11 The frontend did not sanitize Markdown output, like in persistent notifications. Render Markdown through a sanitizer. Today that is <ha-markdown>. See frontend.

Login and the frontend

Four findings from the 2023 audit by Cure53, all fixed in Home Assistant Core 2023.9.

Date What went wrong Lesson
2023‑10‑19 A redirect_uri published by a login client was not checked for its scheme, so a javascript: URL could run code in the frontend. Every URL from outside gets its scheme checked before it is used as a link or a redirect. See frontend.
2023‑10‑19 A login link could send the authorization code to another site that the attacker controlled. Redirect targets need a strict match with the client they belong to.
2023‑10‑19 A parameter in a login link decided which server the frontend opened its WebSocket to, so a link could connect it to a fake server. Never let a URL parameter pick the server the frontend trusts.
2023‑10‑19 Home Assistant did not set the X-Frame-Options header, so other sites could load it in a frame for clickjacking. Core now sends X-Frame-Options: SAMEORIGIN by default. Do not work around it.

Endpoints without a login

An endpoint that answered without checking who was asking. Being on the local network is not a login.

Date What went wrong Lesson
2026‑06‑18 An HTTP view of the legacy Konnected integration had requires_auth = False and checked a token on POST and PUT, but not on GET. Anyone on the network could read the state of the alarm panel. The integration was removed. With requires_auth = False, every method of the view checks the request itself. See integrations.
2023‑12‑14 The login page showed all user accounts to anyone on the local network who opened it. Do not hand out information about users before login, not even on the local network.
2023‑10‑19 Webhooks marked as local only were reachable from the internet through the remote connection of Home Assistant Cloud, now Home Assistant Link, which made requests look local. Where a request comes from is not the same as who sent it. Use local_only from the webhook helper, which handles this case. See integrations.

Server-side request forgery

Data from a caller ended up in a request that Home Assistant itself sent, with its own credentials.

Date What went wrong Lesson
2023‑10‑19 The addon field of the hassio.addon_stdin action was put into the path of a Supervisor API request, so a caller could reach other Supervisor endpoints. Validate every value that goes into a URL or a path, with a strict pattern. Core now checks that field against a slug pattern. See integrations.

Certificate checks

Date What went wrong Lesson
2025‑02‑18 When the verify_ssl option of aiohttp was replaced by ssl, some integrations and libraries passed the old value straight on. According to the advisory, that turned certificate checks off. Use the shared web session of Home Assistant, and pass the choice of the user as verify_ssl. See integrations.

Apps and the Supervisor

Date What went wrong Lesson
2026‑03‑27 Apps on the host network served endpoints without a login on the internal network of the Supervisor, assuming nothing else could reach it. Devices on the local network could. Binding to an internal address is not a login. See apps.
2023‑03‑08 Attackers could bypass authentication and reach the Supervisor API through Home Assistant. A proxy only forwards what is on an explicit list. See apps.

Companion apps

The companion apps hold a token for the server of the user. Anything that can make the app act on its own uses that token.

Date What went wrong Lesson
2026‑07‑31 Other apps could open a tag link in the Android app, which sent the tag scan to the server without asking the user. An action that comes from outside the app needs the user's approval. See companion apps.
2026‑07‑31 The same for the iOS app, through a universal link. The same lesson, on both platforms. See companion apps.
2026‑07‑26 An invite link could start onboarding of the Android app against any server, without showing its address. A fake login page could then collect the password. Show the user where a link takes them before they trust it. See companion apps.
2026‑06‑25 The iOS app ignored the list of home Wi-Fi networks for the internal URL, so it could send its token over plain HTTP on any network. Only use an internal http: URL on a network the user marked as home. See companion apps.
2026‑06‑17 An exported receiver of the Android app accepted location updates from any app, and sent them to the server as the real location. Do not export components. When something must be reachable, accept only the one action it needs, and drop the data that comes with it. See companion apps.
2026‑05‑11 The JavaScript bridge of both apps answered frames from other origins, like a Webpage card, and put a callback name from the message into code it ran. A page in a frame could get the access token. Only the main frame of the server talks to the bridge, and nothing from a message becomes code. See companion apps.
2023‑10‑19 The Android app could be made to load an arbitrary URL in its WebView. The WebView only loads the server of the user. See companion apps.
2023‑10‑19 A link or QR code could make the iOS and macOS app call actions on the server without asking. An action that comes from outside the app needs the user's approval. See companion apps.

Workflows

Date What went wrong Lesson
2023‑10‑19 A shared GitHub Action of the project put the branch name of a pull request straight into a shell script, an expression injection. Never put ${{ }} expressions with outside data in a run: step. See dependencies and supply chain.
Was this page helpful?

Last updated on .