diff --git a/apps/web/src/serlo-editor-integration/create-renderers.tsx b/apps/web/src/serlo-editor-integration/create-renderers.tsx index 920df59237..effca42818 100644 --- a/apps/web/src/serlo-editor-integration/create-renderers.tsx +++ b/apps/web/src/serlo-editor-integration/create-renderers.tsx @@ -29,7 +29,7 @@ import type { EditorDropzoneImageDocument, EditorInteractiveVideoDocument, } from '@editor/types/editor-plugins' -import DOMPurify from 'dompurify' +import { sanitizeHref } from '@editor/utils/sanitize-href' import dynamic from 'next/dynamic' import { ComponentProps } from 'react' @@ -261,14 +261,9 @@ export function createRenderers(): InitRenderersArgs { ), linkRenderer: ({ href, children }: ComponentProps) => { - // href can be manipulated by the user and could potentially be abused to inject malicious javascript. We use DOMPurify to validate the href. - // Examples: - // - 'javascript:doSomethingBad()' -> invalid - // - 'https://example.com/' -> valid - const isHrefValid = DOMPurify.isValidAttribute('a', 'href', href) return ( <> - {children} + {children} {href} ) diff --git a/packages/editor/src/editor-integration/create-renderers.tsx b/packages/editor/src/editor-integration/create-renderers.tsx index 9ed0558363..1ccbc8865c 100644 --- a/packages/editor/src/editor-integration/create-renderers.tsx +++ b/packages/editor/src/editor-integration/create-renderers.tsx @@ -30,7 +30,7 @@ import { TextAreaExerciseStaticRenderer } from '@editor/plugins/text-area-exerci import { VideoStaticRenderer } from '@editor/plugins/video/static' import { EditorPluginType } from '@editor/types/editor-plugin-type' import { TemplatePluginType } from '@editor/types/template-plugin-type' -import DOMPurify from 'dompurify' +import { sanitizeHref } from '@editor/utils/sanitize-href' import { ComponentProps } from 'react' export function createRenderers(): InitRenderersArgs { @@ -125,15 +125,10 @@ export function createRenderers(): InitRenderersArgs { ], mathRenderer: (element: MathElement) => , linkRenderer: ({ href, children }: ComponentProps) => { - // href can be manipulated by the user and could potentially be abused to inject malicious javascript. We use DOMPurify to validate the href. - // Examples: - // - 'javascript:doSomethingBad()' -> invalid - // - 'https://example.com/' -> valid - const isHrefValid = DOMPurify.isValidAttribute('a', 'href', href) return ( diff --git a/packages/editor/src/plugins/text/hooks/use-slate-render-handlers.tsx b/packages/editor/src/plugins/text/hooks/use-slate-render-handlers.tsx index 446cfc808f..a99862356b 100644 --- a/packages/editor/src/plugins/text/hooks/use-slate-render-handlers.tsx +++ b/packages/editor/src/plugins/text/hooks/use-slate-render-handlers.tsx @@ -1,3 +1,4 @@ +import { sanitizeHref } from '@editor/utils/sanitize-href' import { createElement, useCallback } from 'react' import { RenderElementProps, RenderLeafProps } from 'slate-react' @@ -29,7 +30,7 @@ export const useSlateRenderHandlers = ({ if (element.type === 'a') { return ( diff --git a/packages/editor/src/utils/sanitize-href.ts b/packages/editor/src/utils/sanitize-href.ts new file mode 100644 index 0000000000..3ff20e4475 --- /dev/null +++ b/packages/editor/src/utils/sanitize-href.ts @@ -0,0 +1,11 @@ +import DOMPurify from 'dompurify' + +export function sanitizeHref(href: string) { + // Users can add links to content in the editor. So, href can be manipulated by the user and could potentially be abused to inject malicious javascript. We use DOMPurify to validate the href. + // Examples: + // - 'javascript:doSomethingBad()' -> invalid + // - 'https://example.com/' -> valid + const isHrefValid = DOMPurify.isValidAttribute('a', 'href', href) + + return isHrefValid ? href : '' +}