From 0ae9b383d61d8489fa6903284fb45cc0b0b72c25 Mon Sep 17 00:00:00 2001 From: David Luzar <5153846+dwelle@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:57:43 +0200 Subject: [PATCH] fix: Gist embed allowing unsafe html (#7883) --- packages/excalidraw/components/App.tsx | 4 +- packages/excalidraw/element/embeddable.ts | 68 ++++++++--------------- packages/excalidraw/element/types.ts | 1 + 3 files changed, 27 insertions(+), 46 deletions(-) diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index e49b04c621..322096d634 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -1212,7 +1212,9 @@ class App extends React.Component { title="Excalidraw Embedded Content" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen={true} - sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-downloads" + sandbox={`${ + src?.sandbox?.allowSameOrigin ? "allow-same-origin" : "" + } allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-downloads`} /> )} diff --git a/packages/excalidraw/element/embeddable.ts b/packages/excalidraw/element/embeddable.ts index e171770400..40213aff83 100644 --- a/packages/excalidraw/element/embeddable.ts +++ b/packages/excalidraw/element/embeddable.ts @@ -18,20 +18,20 @@ const RE_YOUTUBE = /^(?:http(?:s)?:\/\/)?(?:www\.)?youtu(?:be\.com|\.be)\/(embed\/|watch\?v=|shorts\/|playlist\?list=|embed\/videoseries\?list=)?([a-zA-Z0-9_-]+)(?:\?t=|&t=|\?start=|&start=)?([a-zA-Z0-9_-]+)?[^\s]*$/; const RE_VIMEO = - /^(?:http(?:s)?:\/\/)?(?:(?:w){3}.)?(?:player\.)?vimeo\.com\/(?:video\/)?([^?\s]+)(?:\?.*)?$/; + /^(?:http(?:s)?:\/\/)?(?:(?:w){3}\.)?(?:player\.)?vimeo\.com\/(?:video\/)?([^?\s]+)(?:\?.*)?$/; const RE_FIGMA = /^https:\/\/(?:www\.)?figma\.com/; const RE_GH_GIST = /^https:\/\/gist\.github\.com/; const RE_GH_GIST_EMBED = - /^ twitter embeds -const RE_TWITTER = /(?:http(?:s)?:\/\/)?(?:(?:w){3}.)?(?:twitter|x).com/; +const RE_TWITTER = /(?:https?:\/\/)?(?:(?:w){3}\.)?(?:twitter|x)\.com/; const RE_TWITTER_EMBED = - /^$/i; @@ -153,46 +153,24 @@ export const getEmbedLink = ( // the embed srcdoc still supports twitter.com domain only link = link.replace(/\bx.com\b/, "twitter.com"); - let ret: IframeData; - // assume embed code - if (/
srcDoc, - intrinsicSize: { w: 480, h: 480 }, - }; - // assume regular tweet url - } else { - ret = { - type: "document", - srcdoc: (theme: string) => - createSrcDoc( - ` `, - ), - intrinsicSize: { w: 480, h: 480 }, - }; - } + const ret: IframeData = { + type: "document", + srcdoc: (theme: string) => + createSrcDoc( + ` `, + ), + intrinsicSize: { w: 480, h: 480 }, + sandbox: { allowSameOrigin: true }, + }; embeddedLinkCache.set(originalLink, ret); return ret; } if (RE_GH_GIST.test(link)) { - let ret: IframeData; - // assume embed code - if (/ `), - intrinsicSize: { w: 550, h: 720 }, - }; - } + intrinsicSize: { w: 550, h: 720 }, + }; embeddedLinkCache.set(link, ret); return ret; } @@ -313,8 +290,8 @@ export const maybeParseEmbedSrc = (str: string): string => { } const gistMatch = str.match(RE_GH_GIST_EMBED); - if (gistMatch && gistMatch.length === 2) { - return gistMatch[1]; + if (gistMatch && gistMatch.length === 3) { + return `https://gist.github.com/${gistMatch[1]}/${gistMatch[2]}`; } if (RE_GIPHY.test(str)) { @@ -325,6 +302,7 @@ export const maybeParseEmbedSrc = (str: string): string => { if (match && match.length === 2) { return match[1]; } + return str; }; diff --git a/packages/excalidraw/element/types.ts b/packages/excalidraw/element/types.ts index 8d3a0d4ef7..2ee9a12b09 100644 --- a/packages/excalidraw/element/types.ts +++ b/packages/excalidraw/element/types.ts @@ -111,6 +111,7 @@ export type IframeData = | { intrinsicSize: { w: number; h: number }; error?: Error; + sandbox?: { allowSameOrigin?: boolean }; } & ( | { type: "video" | "generic"; link: string } | { type: "document"; srcdoc: (theme: Theme) => string }