Summary
The Iframe widget currently renders a bare <iframe src> with no way to set the sandbox attribute. Additionally, LocalFileController serves text/html with no Content Security Policy (CSP). This means HTML served from /ivy/local-file runs with the same origin as the app and has full privileges — any script in an embedded dashboard can call app endpoints and access other local-file paths.
Proposed Solution
-
Add a sandbox prop to the Iframe widget (both C# builder and IframeWidget.tsx)
- Host should pass
sandbox="allow-scripts" by default
- Omit
allow-same-origin to create a null origin, which neutralizes the escalation
-
Optionally add configurable CSP on local-file text/html responses
Both features should be opt-in.
Files to Modify
src/frontend/src/widgets/primitives/IframeWidget.tsx
src/Ivy/Services/LocalFileController.cs
Additional Context
This is a security issue that prevents scripts in embedded dashboards from accessing privileged app endpoints and local-file paths.
Original Slack thread
Reported by Renco Smeding
Summary
The
Iframewidget currently renders a bare<iframe src>with no way to set thesandboxattribute. Additionally,LocalFileControllerservestext/htmlwith no Content Security Policy (CSP). This means HTML served from/ivy/local-fileruns with the same origin as the app and has full privileges — any script in an embedded dashboard can call app endpoints and access otherlocal-filepaths.Proposed Solution
Add a
sandboxprop to theIframewidget (both C# builder andIframeWidget.tsx)sandbox="allow-scripts"by defaultallow-same-originto create a null origin, which neutralizes the escalationOptionally add configurable CSP on local-file
text/htmlresponsesBoth features should be opt-in.
Files to Modify
src/frontend/src/widgets/primitives/IframeWidget.tsxsrc/Ivy/Services/LocalFileController.csAdditional Context
This is a security issue that prevents scripts in embedded dashboards from accessing privileged app endpoints and local-file paths.
Original Slack thread
Reported by Renco Smeding