fix(security): restrict link protocols to http and https (#1888)

This commit is contained in:
Meier Lukas
2025-01-10 14:45:30 +01:00
committed by GitHub
parent 80c02ef9f2
commit a12dd10269
5 changed files with 41 additions and 4 deletions

View File

@@ -1,7 +1,7 @@
"use client";
import { Box, Stack, Text, Title } from "@mantine/core";
import { IconBrowserOff } from "@tabler/icons-react";
import { IconBrowserOff, IconProtocol } from "@tabler/icons-react";
import { objectEntries } from "@homarr/common";
import { useI18n } from "@homarr/translation/client";
@@ -15,6 +15,9 @@ export default function IFrameWidget({ options, isEditMode }: WidgetComponentPro
const allowedPermissions = getAllowedPermissions(permissions);
if (embedUrl.trim() === "") return <NoUrl />;
if (!isSupportedProtocol(embedUrl)) {
return <UnsupportedProtocol />;
}
return (
<Box h="100%" w="100%">
@@ -31,6 +34,17 @@ export default function IFrameWidget({ options, isEditMode }: WidgetComponentPro
);
}
const supportedProtocols = ["http", "https"];
const isSupportedProtocol = (url: string) => {
try {
const parsedUrl = new URL(url);
return supportedProtocols.map((protocol) => `${protocol}:`).includes(`${parsedUrl.protocol}`);
} catch {
return false;
}
};
const NoUrl = () => {
const t = useI18n();
@@ -42,6 +56,21 @@ const NoUrl = () => {
);
};
const UnsupportedProtocol = () => {
const t = useI18n();
return (
<Stack align="center" justify="center" h="100%">
<IconProtocol />
<Title order={4} ta="center">
{t("widget.iframe.error.unsupportedProtocol", {
supportedProtocols: supportedProtocols.map((protocol) => protocol).join(", "),
})}
</Title>
</Stack>
);
};
const getAllowedPermissions = (permissions: Omit<WidgetComponentProps<"iframe">["options"], "embedUrl">) => {
return objectEntries(permissions)
.filter(([_key, value]) => value)