mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-11-24 03:39:01 +08:00
fix(extension-youtube) XSS risk with src tag
Fixes risks outline in #4600 by verifying that any src urls are valid youtube URLs before rendering as HTML. My thoughts are that this attack vector would be difficult to use because the attacker would have to have a way to manipualte the TipTap payload in a manner that bypasses the youtube extension's `setYoutubeVideo` command, which already checks for valid URLs.
This commit is contained in:
parent
acbf47e5a7
commit
04a11355a7
@ -52,6 +52,10 @@ export const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {
|
|||||||
startAt,
|
startAt,
|
||||||
} = options
|
} = options
|
||||||
|
|
||||||
|
if (!isValidYoutubeUrl(url)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// if is already an embed url, return it
|
// if is already an embed url, return it
|
||||||
if (url.includes('/embed/')) {
|
if (url.includes('/embed/')) {
|
||||||
return url
|
return url
|
||||||
|
59
tests/cypress/integration/extensions/youtube.spec.ts
Normal file
59
tests/cypress/integration/extensions/youtube.spec.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { Editor } from '@tiptap/core'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Youtube from '@tiptap/extension-youtube'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Most youtube tests should actually exist in the demo/ app folder
|
||||||
|
*/
|
||||||
|
describe('extension-youtube', () => {
|
||||||
|
const editorElClass = 'tiptap'
|
||||||
|
let editor: Editor | null = null
|
||||||
|
|
||||||
|
const createEditorEl = () => {
|
||||||
|
const editorEl = document.createElement('div')
|
||||||
|
|
||||||
|
editorEl.classList.add(editorElClass)
|
||||||
|
document.body.appendChild(editorEl)
|
||||||
|
return editorEl
|
||||||
|
}
|
||||||
|
const getEditorEl = () => document.querySelector(`.${editorElClass}`)
|
||||||
|
|
||||||
|
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)//embed/',
|
||||||
|
'https://youtube.google.com/embed/fdsafsdf',
|
||||||
|
]
|
||||||
|
|
||||||
|
invalidUrls.forEach(url => {
|
||||||
|
it(`does not output html for javascript schema or non-youtube links for url ${url}`, () => {
|
||||||
|
editor = new Editor({
|
||||||
|
element: createEditorEl(),
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Text,
|
||||||
|
Paragraph,
|
||||||
|
Youtube,
|
||||||
|
],
|
||||||
|
content: {
|
||||||
|
type: 'doc',
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'youtube',
|
||||||
|
attrs: {
|
||||||
|
src: url,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(editor.getHTML()).to.not.include(url)
|
||||||
|
|
||||||
|
editor?.destroy()
|
||||||
|
getEditorEl()?.remove()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user