diff --git a/src/app/[locale]/blog/[slug]/page.tsx b/src/app/[locale]/blog/[slug]/page.tsx
index 998a881..a570b3b 100644
--- a/src/app/[locale]/blog/[slug]/page.tsx
+++ b/src/app/[locale]/blog/[slug]/page.tsx
@@ -32,6 +32,22 @@ interface LinkValue {
href: string
}
+const SAFE_LINK_PROTOCOLS = ["http:", "https:", "mailto:"]
+
+// Links come from the CMS, so reject schemes like javascript: that would run
+// code when clicked. Parsing with URL also catches tricks like leading
+// whitespace or mixed case that a simple prefix check would miss
+const getSafeHref = (href?: string) => {
+ if (!href) return null
+
+ try {
+ const { protocol } = new URL(href, "https://uiogaming.no")
+ return SAFE_LINK_PROTOCOLS.includes(protocol) ? href : null
+ } catch {
+ return null
+ }
+}
+
// Render posts on first visit and cache them, instead of on every request
export async function generateStaticParams() {
return []
@@ -85,16 +101,21 @@ const components: PortableTextComponents = {
}: {
children?: React.ReactNode
value?: LinkValue
- }) => (
-
- {children}
-
- ),
+ }) => {
+ const href = getSafeHref(value?.href)
+ if (!href) return <>{children}>
+
+ return (
+
+ {children}
+
+ )
+ },
},
}