fix: allow same-origin iframe paths

This commit is contained in:
ajnart committed 2026-08-26 15:07:49 +02:00
1 parent 16e437decc
commit 254438247e
3 files changed
+24 -5

No files matched your search

+3 -3
View File
@@ -7,13 +7,13 @@ import { objectEntries } from "@homarr/common";
import { useI18n } from "@homarr/translation/client";
import type { WidgetComponentProps } from "../definition";
import { getSafeApplicationUrl } from "../common/application-url";
import classes from "./component.module.css";
import { getSafeIframeUrl } from "./url";
export default function IFrameWidget({ options, isEditMode }: WidgetComponentProps<"iframe">) {
const t = useI18n("widget.iframe");
const { embedUrl, allowScrolling, ...permissions } = options;
const safeEmbedUrl = getSafeApplicationUrl(embedUrl);
const safeEmbedUrl = getSafeIframeUrl(embedUrl);
const allowedPermissions = getAllowedPermissions(permissions);
const sandboxFlags = getSandboxFlags(permissions);
@@ -45,7 +45,7 @@ export default function IFrameWidget({ options, isEditMode }: WidgetComponentPro
const supportedProtocols = ["http", "https"];
export const isSupportedProtocol = (url: string) => {
return getSafeApplicationUrl(url) !== undefined;
return getSafeIframeUrl(url) !== undefined;
};
const NoUrl = () => {
+2 -2
View File
@@ -1,8 +1,8 @@
import { IconBrowser, IconExternalLink } from "@tabler/icons-react";
import { createWidgetDefinition } from "../definition";
import { getSafeApplicationUrl } from "../common/application-url";
import { optionsBuilder } from "../options";
import { getSafeIframeUrl } from "./url";
const createOptions = () =>
optionsBuilder.from((factory) => ({
@@ -23,7 +23,7 @@ export const { definition, componentLoader } = createWidgetDefinition("iframe",
supportsAdvancedFocus: false,
icon: IconBrowser,
contextActions: ({ options }) => {
const embedUrl = getSafeApplicationUrl(options.embedUrl);
const embedUrl = getSafeIframeUrl(options.embedUrl);
return embedUrl
? [
{
+19
View File
@@ -0,0 +1,19 @@
import { getSafeApplicationUrl } from "../common/application-url";
const relativeUrlBase = "https://homarr.invalid";
export const getSafeIframeUrl = (value: unknown): string | undefined => {
const absoluteUrl = getSafeApplicationUrl(value);
if (absoluteUrl) return absoluteUrl;
if (typeof value !== "string") return undefined;
const path = value.trim();
if (!path.startsWith("/")) return undefined;
const resolvedUrl = getSafeApplicationUrl(path, { baseUrl: relativeUrlBase });
if (!resolvedUrl) return undefined;
const parsedUrl = new URL(resolvedUrl);
if (parsedUrl.origin !== relativeUrlBase) return undefined;
return `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`;
};