diff --git a/frontend/src/components/common/html-to-react/__snapshots__/html-to-react.spec.tsx.snap b/frontend/src/components/common/html-to-react/__snapshots__/html-to-react.spec.tsx.snap
index 83f048ac9..3cc18fda8 100644
--- a/frontend/src/components/common/html-to-react/__snapshots__/html-to-react.spec.tsx.snap
+++ b/frontend/src/components/common/html-to-react/__snapshots__/html-to-react.spec.tsx.snap
@@ -27,4 +27,40 @@ exports[`HTML to React will forward the parser options 1`] = `
 </div>
 `;
 
+exports[`HTML to React will render links with non-http protocols 1`] = `
+<div>
+  <a
+    href="tel:+1234567890"
+  >
+    tel
+  </a>
+  <a
+    href="mailto:test@example.com"
+  >
+    mailto
+  </a>
+  <a
+    href="geo:25.197,55.274"
+  >
+    geo
+  </a>
+  <a
+    href="xmpp:test"
+  >
+    xmpp
+  </a>
+</div>
+`;
+
+exports[`HTML to React won't render script links 1`] = `
+<div>
+  <a>
+    js
+  </a>
+  <a>
+    vbs
+  </a>
+</div>
+`;
+
 exports[`HTML to React won't render script tags 1`] = `<div />`;
diff --git a/frontend/src/components/common/html-to-react/html-to-react.spec.tsx b/frontend/src/components/common/html-to-react/html-to-react.spec.tsx
index 2c74c1f04..9a1f956b5 100644
--- a/frontend/src/components/common/html-to-react/html-to-react.spec.tsx
+++ b/frontend/src/components/common/html-to-react/html-to-react.spec.tsx
@@ -17,6 +17,24 @@ describe('HTML to React', () => {
     expect(view.container).toMatchSnapshot()
   })
 
+  it("won't render script links", () => {
+    const view = render(
+      <HtmlToReact htmlCode={'<a href="javascript:alert(true)">js</a><a href="vbscript:WScript.Evil">vbs</a>'} />
+    )
+    expect(view.container).toMatchSnapshot()
+  })
+
+  it('will render links with non-http protocols', () => {
+    const view = render(
+      <HtmlToReact
+        htmlCode={
+          '<a href="tel:+1234567890">tel</a><a href="mailto:test@example.com">mailto</a><a href="geo:25.197,55.274">geo</a><a href="xmpp:test">xmpp</a>'
+        }
+      />
+    )
+    expect(view.container).toMatchSnapshot()
+  })
+
   it('will forward the DomPurify settings', () => {
     const view = render(
       <HtmlToReact domPurifyConfig={{ ADD_TAGS: ['test-tag'] }} htmlCode={'<test-tag>Test!</test-tag>'} />
diff --git a/frontend/src/components/common/html-to-react/html-to-react.tsx b/frontend/src/components/common/html-to-react/html-to-react.tsx
index 44e85edf3..e73486793 100644
--- a/frontend/src/components/common/html-to-react/html-to-react.tsx
+++ b/frontend/src/components/common/html-to-react/html-to-react.tsx
@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
+ * SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file)
  *
  * SPDX-License-Identifier: AGPL-3.0-only
  */
@@ -16,6 +16,8 @@ export interface HtmlToReactProps {
   parserOptions?: ParserOptions
 }
 
+const REGEX_URI_SCHEME_NO_SCRIPTS = /^(?!.*script:).+:?/i
+
 /**
  * Renders
  * @param htmlCode
@@ -26,7 +28,12 @@ export interface HtmlToReactProps {
 export const HtmlToReact: React.FC<HtmlToReactProps> = ({ htmlCode, domPurifyConfig, parserOptions }) => {
   const elements = useMemo(() => {
     const sanitizedHtmlCode = measurePerformance('html-to-react: sanitize', () => {
-      return sanitize(htmlCode, { ...domPurifyConfig, RETURN_DOM_FRAGMENT: false, RETURN_DOM: false })
+      return sanitize(htmlCode, {
+        ...domPurifyConfig,
+        RETURN_DOM_FRAGMENT: false,
+        RETURN_DOM: false,
+        ALLOWED_URI_REGEXP: REGEX_URI_SCHEME_NO_SCRIPTS
+      })
     })
     return measurePerformance('html-to-react: convertHtmlToReact', () => {
       return convertHtmlToReact(sanitizedHtmlCode, parserOptions)