diff --git a/packages/extension-link/src/link.ts b/packages/extension-link/src/link.ts index e3af421de65..2926ea43dbd 100644 --- a/packages/extension-link/src/link.ts +++ b/packages/extension-link/src/link.ts @@ -161,9 +161,7 @@ export const Link = Mark.create({ }, renderHTML({ HTMLAttributes }) { - // False positive; we're explicitly checking for javascript: links to ignore them - // eslint-disable-next-line no-script-url - if (HTMLAttributes.href?.startsWith('javascript:')) { + if (HTMLAttributes.href?.substring(0, HTMLAttributes.href.indexOf(':')).toLowerCase().trim() === 'javascript') { // strip out the href return ['a', mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: '' }), 0] } diff --git a/tests/cypress/integration/extensions/link.spec.ts b/tests/cypress/integration/extensions/link.spec.ts index edb729093d5..9495264607c 100644 --- a/tests/cypress/integration/extensions/link.spec.ts +++ b/tests/cypress/integration/extensions/link.spec.ts @@ -20,45 +20,55 @@ describe('extension-link', () => { } const getEditorEl = () => document.querySelector(`.${editorElClass}`) - it('does not output src tag for javascript schema', () => { - editor = new Editor({ - element: createEditorEl(), - extensions: [ - Document, - Text, - Paragraph, - Link, - ], - content: { - type: 'doc', - content: [ - { - type: 'paragraph', - content: [ - { - type: 'text', - text: 'hello world!', - marks: [ - { - type: 'link', - attrs: { - // We have to disable the eslint rule here because we're trying to purposely test eval urls - // eslint-disable-next-line no-script-url - href: 'javascript:alert(window.origin)', - }, - }, - ], - }, - ], - }, + const invalidUrls = [ + // We have to disable the eslint rule here because we're trying to purposely test eval urls + // eslint-disable-next-line no-script-url + 'javascript:alert(window.origin)', + // eslint-disable-next-line no-script-url + ' javascript:alert(window.origin)', + // eslint-disable-next-line no-script-url + 'jAvAsCrIpT:alert(window.origin)', + ] + + invalidUrls.forEach(url => { + it('does not output src tag for javascript schema', () => { + editor = new Editor({ + element: createEditorEl(), + extensions: [ + Document, + Text, + Paragraph, + Link, ], - }, - }) + content: { + type: 'doc', + content: [ + { + type: 'paragraph', + content: [ + { + type: 'text', + text: 'hello world!', + marks: [ + { + type: 'link', + attrs: { + href: url, + }, + }, + ], + }, + ], + }, + ], + }, + }) - // eslint-disable-next-line no-script-url - expect(editor.getHTML()).to.not.include('javascript:alert(window.origin)') + // eslint-disable-next-line no-script-url + expect(editor.getHTML()).to.not.include('javascript:alert(window.origin)') - editor?.destroy() - getEditorEl()?.remove() + editor?.destroy() + getEditorEl()?.remove() + }) }) }) diff --git a/tests/cypress/integration/extensions/youtube.spec.ts b/tests/cypress/integration/extensions/youtube.spec.ts index 698d2816ab4..2d9f5fc2024 100644 --- a/tests/cypress/integration/extensions/youtube.spec.ts +++ b/tests/cypress/integration/extensions/youtube.spec.ts @@ -24,6 +24,10 @@ describe('extension-youtube', () => { // We have to disable the eslint rule here because we're trying to purposely test eval urls // eslint-disable-next-line no-script-url 'javascript:alert(window.origin)//embed/', + // eslint-disable-next-line no-script-url + ' javascript:alert(window.origin)', + // eslint-disable-next-line no-script-url + 'jAvAsCrIpT:alert(window.origin)//embed/', 'https://youtube.google.com/embed/fdsafsdf', 'https://youtube.com.bad/embed', ]