diff --git a/packages/preview/package.json b/packages/preview/package.json index 491c1b82a679e..d5f2081d490f6 100644 --- a/packages/preview/package.json +++ b/packages/preview/package.json @@ -10,9 +10,11 @@ "@types/highlight.js": "^9.12.2", "@types/markdown-it": "*", "@types/markdown-it-anchor": "^4.0.1", + "@types/dompurify": "^2.0.2", "highlight.js": "^9.12.0", "markdown-it": "^8.4.0", - "markdown-it-anchor": "~5.0.0" + "markdown-it-anchor": "~5.0.0", + "dompurify": "^2.0.11" }, "publishConfig": { "access": "public" diff --git a/packages/preview/src/browser/markdown/markdown-preview-handler.spec.ts b/packages/preview/src/browser/markdown/markdown-preview-handler.spec.ts index e556646ed7494..8605bcb0d4fcf 100644 --- a/packages/preview/src/browser/markdown/markdown-preview-handler.spec.ts +++ b/packages/preview/src/browser/markdown/markdown-preview-handler.spec.ts @@ -130,11 +130,11 @@ See [here](https://github.com/eclipse-theia/theia). `; const exampleHtml1 = // - `

Theia - Preview Extension

-

Shows a preview of supported resources. + `

Theia - Preview Extension

+

Shows a preview of supported resources. See here.

-

License

-

Apache-2.0

+

License

+

Apache-2.0

`; const exampleMarkdown2 = // @@ -143,8 +143,8 @@ const exampleMarkdown2 = // `; const exampleHtml2 = // - `

Heading

-

alternativetext

+ `

Heading

+

alternativetext

`; const exampleMarkdown3 = // @@ -156,10 +156,10 @@ const exampleMarkdown3 = // `; const exampleHtml3 = // - `

Block HTML Image

-tada -

Block HTML Image

-tada + `

Block HTML Image

+tada +

Block HTML Image

+tada `; const exampleMarkdown4 = // @@ -168,8 +168,8 @@ text in paragraph tada `; const exampleHtml4 = // - `

Inlined HTML Image

-

text in paragraph tada

+ `

Inlined HTML Image

+

text in paragraph tada

`; const exampleMarkdown5 = // @@ -184,12 +184,12 @@ word

`; const exampleHtml5 = // - `

Multiple HTML Images nested in blocks

-

word

-tada

+ `

Multiple HTML Images nested in blocks

+

word

+tada

-tada +tada

`; diff --git a/packages/preview/src/browser/markdown/markdown-preview-handler.ts b/packages/preview/src/browser/markdown/markdown-preview-handler.ts index ea117928cf669..e8907d169e55b 100644 --- a/packages/preview/src/browser/markdown/markdown-preview-handler.ts +++ b/packages/preview/src/browser/markdown/markdown-preview-handler.ts @@ -23,6 +23,7 @@ import { Path } from '@theia/core/lib/common/path'; import * as hljs from 'highlight.js'; import * as markdownit from 'markdown-it'; import * as anchor from 'markdown-it-anchor'; +import * as DOMPurify from 'dompurify'; import { PreviewUri } from '../preview-uri'; import { PreviewHandler, RenderContentParams } from '../preview-handler'; import { PreviewOpenerOptions } from '../preview-contribution'; @@ -51,9 +52,10 @@ export class MarkdownPreviewHandler implements PreviewHandler { renderContent(params: RenderContentParams): HTMLElement { const content = params.content; const renderedContent = this.getEngine().render(content, params); + const sanitizedContent = DOMPurify.sanitize(renderedContent); const contentElement = document.createElement('div'); contentElement.classList.add(this.contentClass); - contentElement.innerHTML = renderedContent; + contentElement.innerHTML = sanitizedContent; this.addLinkClickedListener(contentElement, params); return contentElement; } diff --git a/yarn.lock b/yarn.lock index dce9900cd0159..a0cefbd5d2315 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1127,6 +1127,13 @@ resolved "https://registry.yarnpkg.com/@types/domhandler/-/domhandler-2.4.1.tgz#7b3b347f7762180fbcb1ece1ce3dd0ebbb8c64cf" integrity sha512-cfBw6q6tT5sa1gSPFSRKzF/xxYrrmeiut7E0TxNBObiLSBTuFEHibcfEe3waQPEDbqBsq+ql/TOniw65EyDFMA== +"@types/dompurify@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.0.2.tgz#94b5c05dc9b8a682a0abb4a8d6f0b82df61baeac" + integrity sha512-WHoQQTziRHm5/Fw/KsUKyh2V+wd3k2QUpJyjUXo8K7d9kMJ5i5wQnGDkO4URkwulhY2HuM/gbX25nSooi6+wUA== + dependencies: + "@types/trusted-types" "*" + "@types/domutils@*": version "1.7.2" resolved "https://registry.yarnpkg.com/@types/domutils/-/domutils-1.7.2.tgz#89422e579c165994ad5c09ce90325da596cc105d" @@ -1471,6 +1478,11 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.6.tgz#c880579e087d7a0db13777ff8af689f4ffc7b0d5" integrity sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ== +"@types/trusted-types@*": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-1.0.4.tgz#922d092c84a776a59acb0bd6785fd82b59b9bad5" + integrity sha512-6jtHrHpmiXOXoJ31Cg9R+iEVwuEKPf0XHwFUI93eEPXx492/J2JHyafkleKE2EYzZprayk9FSjTyK1GDqcwDng== + "@types/uglify-js@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" @@ -4854,6 +4866,11 @@ domhandler@^3.0.0: dependencies: domelementtype "^2.0.1" +dompurify@^2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.0.11.tgz#cd47935774230c5e478b183a572e726300b3891d" + integrity sha512-qVoGPjIW9IqxRij7klDQQ2j6nSe4UNWANBhZNLnsS7ScTtLb+3YdxkRY8brNTpkUiTtcXsCJO+jS0UCDfenLuA== + domutils@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.0.0.tgz#15b8278e37bfa8468d157478c58c367718133c08"