Skip to content

Commit 8abdad9

Browse files
balloobclaude
andcommitted
Sandbox add-on ingress iframe without allow-same-origin
Split IFRAME_SANDBOX into two constants: IFRAME_SANDBOX (without allow-same-origin) for add-on ingress iframes that need origin isolation, and IFRAME_SANDBOX_SAME_ORIGIN for external iframes that need same-origin access. This ensures add-on iframes can't inherit camera/microphone permissions already granted to the Home Assistant origin, and prevents same-origin iframes from removing their own sandbox. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e5d4d97 commit 8abdad9

4 files changed

Lines changed: 9 additions & 5 deletions

File tree

src/panels/app/ha-panel-app.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { classMap } from "lit/directives/class-map";
66
import { createRef, ref } from "lit/directives/ref";
77
import memoizeOne from "memoize-one";
88
import { fireEvent } from "../../common/dom/fire_event";
9+
import { IFRAME_SANDBOX } from "../../util/iframe";
910
import { navigate } from "../../common/navigate";
1011
import { computeRouteTail } from "../../common/url/route";
1112
import { nextRender } from "../../common/util/render-status";
@@ -136,6 +137,7 @@ class HaPanelApp extends LitElement {
136137
})}
137138
title=${this._addon.name}
138139
src=${this._addon.ingress_url!}
140+
.sandbox=${IFRAME_SANDBOX}
139141
allow="microphone; camera; clipboard-write"
140142
@load=${this._checkLoaded}
141143
${ref(this._iframeRef)}

src/panels/iframe/ha-panel-iframe.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ifDefined } from "lit/directives/if-defined";
44
import "../../layouts/hass-error-screen";
55
import "../../layouts/hass-subpage";
66
import type { HomeAssistant, PanelInfo } from "../../types";
7-
import { IFRAME_SANDBOX } from "../../util/iframe";
7+
import { IFRAME_SANDBOX_SAME_ORIGIN } from "../../util/iframe";
88

99
@customElement("ha-panel-iframe")
1010
class HaPanelIframe extends LitElement {
@@ -41,7 +41,7 @@ class HaPanelIframe extends LitElement {
4141
this.panel.title === null ? undefined : this.panel.title
4242
)}
4343
src=${this.panel.config.url}
44-
.sandbox=${IFRAME_SANDBOX}
44+
.sandbox=${IFRAME_SANDBOX_SAME_ORIGIN}
4545
allow="fullscreen"
4646
></iframe>
4747
</hass-subpage>

src/panels/lovelace/cards/hui-iframe-card.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import type {
1313
LovelaceGridOptions,
1414
} from "../types";
1515
import type { IframeCardConfig } from "./types";
16-
import { IFRAME_SANDBOX } from "../../../util/iframe";
16+
import { IFRAME_SANDBOX_SAME_ORIGIN } from "../../../util/iframe";
1717

1818
@customElement("hui-iframe-card")
1919
export class HuiIframeCard extends LitElement implements LovelaceCard {
@@ -95,7 +95,7 @@ export class HuiIframeCard extends LitElement implements LovelaceCard {
9595
}
9696
const sandbox_params = this._config.disable_sandbox
9797
? undefined
98-
: `${sandbox_user_params} ${IFRAME_SANDBOX}`;
98+
: `${sandbox_user_params} ${IFRAME_SANDBOX_SAME_ORIGIN}`;
9999

100100
return html`
101101
<ha-card

src/util/iframe.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
export const IFRAME_SANDBOX =
2-
"allow-forms allow-popups allow-pointer-lock allow-same-origin allow-scripts allow-modals allow-downloads";
2+
"allow-forms allow-popups allow-pointer-lock allow-scripts allow-modals allow-downloads";
3+
4+
export const IFRAME_SANDBOX_SAME_ORIGIN = `${IFRAME_SANDBOX} allow-same-origin`;

0 commit comments

Comments
 (0)