Skip to content

Commit

Permalink
fix(extension-youtube) XSS risk with src tag
Browse files Browse the repository at this point in the history
Fixes risks outline in ueberdosis#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.
  • Loading branch information
C-Hess authored and janthurau committed Nov 20, 2023
1 parent acbf47e commit 04a1135
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/extension-youtube/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {
startAt,
} = options

if (!isValidYoutubeUrl(url)) {
return null
}

// if is already an embed url, return it
if (url.includes('/embed/')) {
return url
Expand Down
59 changes: 59 additions & 0 deletions tests/cypress/integration/extensions/youtube.spec.ts
Original file line number Diff line number Diff line change
@@ -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()
})
})
})

0 comments on commit 04a1135

Please sign in to comment.