@@ -17,59 +17,18 @@ import React from "react";
17
17
import htmlReactParser , {
18
18
attributesToProps ,
19
19
domToReact ,
20
- Element , Text
20
+ Element ,
21
+ Text ,
21
22
} from "html-react-parser" ;
22
- import stripXSS , { safeAttrValue , whiteList } from "xss" ;
23
- import type { IFilterXSSOptions } from "xss" ;
23
+ import sanitizeHtml from "sanitize-html" ;
24
24
import { useFileContext } from "@cocalc/frontend/lib/file-context" ;
25
25
import DefaultMath from "@cocalc/frontend/components/math/ssr" ;
26
26
import { MathJaxConfig } from "@cocalc/util/mathjax-config" ;
27
27
import { decodeHTML } from "entities" ;
28
28
29
29
const URL_ATTRIBS = [ "src" , "href" , "data" ] ;
30
-
31
30
const MATH_SKIP_TAGS = new Set < string > ( MathJaxConfig . tex2jax . skipTags ) ;
32
31
33
- function getXSSOptions ( urlTransform ) : IFilterXSSOptions | undefined {
34
- // - stripIgnoreTagBody - completely get rid of dangerous HTML
35
- // (otherwise user sees weird mangled style code, when seeing
36
- // nothing would be better).
37
- // - whiteList - we need iframes to support 3d graphics; unfortunately this
38
- // isn't safe without a lot more work, so we do NOT enable them.
39
- return {
40
- stripIgnoreTagBody : true ,
41
- // SECURITY: whitelist note -- we had tried to explicitly allow mathjax script tags in sanitized html
42
- // by whitelisting and scanning. However, this didn't properly work (perhaps due to some update)
43
- // and resulted in a security vulnerability:
44
- // https://github.com/sagemathinc/cocalc/security/advisories/GHSA-8w44-hggw-p5rf
45
- // The fix is completley removing any whitelisting of any script tags. The feature of
46
- // mathjax in html is not important enough to support, and too dangerous -- even if it worked,
47
- // it would probably be an easy attack vector by just making up fake mathjax.
48
- // Due to https://github.com/sagemathinc/cocalc/security/advisories/GHSA-jpjc-pwjv-j9mg
49
- // we also remove all use of iframes, which
50
- whiteList : {
51
- ...whiteList ,
52
- // DISABLED due to https://github.com/sagemathinc/cocalc/security/advisories/GHSA-jpjc-pwjv-j9mg
53
- // iframe: ["src", "srcdoc", "width", "height"],
54
- iframe : [ ] ,
55
- html : [ ] ,
56
- } ,
57
- safeAttrValue : ( tag , name , value ) => {
58
- // disabled since not sufficiently secure.
59
- // if (tag == "iframe" && name == "srcdoc") {
60
- // // important not to mangle this or it won't work.
61
- // return value;
62
- // }
63
- if ( urlTransform && URL_ATTRIBS . includes ( name ) ) {
64
- // use the url transform
65
- return urlTransform ( value , tag , name ) ?? value ;
66
- }
67
- // fallback to the builtin version
68
- return safeAttrValue ( tag , name , value , false as any ) ;
69
- } ,
70
- } ;
71
- }
72
-
73
32
export default function HTML ( {
74
33
value,
75
34
style,
@@ -82,7 +41,30 @@ export default function HTML({
82
41
const { urlTransform, AnchorTagComponent, noSanitize, MathComponent } =
83
42
useFileContext ( ) ;
84
43
if ( ! noSanitize ) {
85
- value = stripXSS ( value , getXSSOptions ( urlTransform ) ) ;
44
+ value = sanitizeHtml ( value , {
45
+ allowedTags : sanitizeHtml . defaults . allowedTags . concat ( [ "img" , "iframe" ] ) ,
46
+ allowedAttributes : {
47
+ ...sanitizeHtml . defaults . allowedAttributes ,
48
+ iframe : [
49
+ "src" ,
50
+ "width" ,
51
+ "height" ,
52
+ "title" ,
53
+ "allow" ,
54
+ "allowfullscreen" ,
55
+ "referrerpolicy" ,
56
+ "loading" ,
57
+ "frameborder" ,
58
+ ] ,
59
+ } ,
60
+ allowedIframeHostnames : [
61
+ "www.youtube.com" ,
62
+ "youtube.com" ,
63
+ "www.youtube-nocookie.com" ,
64
+ "youtube-nocookie.com" ,
65
+ "player.vimeo.com" ,
66
+ ] ,
67
+ } ) ;
86
68
}
87
69
if ( value . trimLeft ( ) . startsWith ( "<html>" ) ) {
88
70
// Sage output formulas are wrapped in "<html>" for some stupid reason, which
@@ -143,28 +125,6 @@ export default function HTML({
143
125
</ AnchorTagComponent >
144
126
) ;
145
127
}
146
- if ( name == "iframe" ) {
147
- // We sandbox and minimize what we allow. Don't
148
- // use {...attribs} due to srcDoc vs srcdoc.
149
- // We don't allow setting the style, since that leads
150
- // to a lot of attacks (i.e., making the iframe move in a
151
- // sneaky way). We have to allow-same-origin or scripts
152
- // won't work at all, which is one of the main uses for
153
- // iframes. A good test is 3d graphics in Sage kernel
154
- // Jupyter notebooks.
155
- // TODO: Except this is a security issue, since
156
- // combining allow-scripts & allow-same-origin makes it
157
- // possible to remove a lot of sandboxing.
158
- return (
159
- < iframe
160
- src = { attribs . src }
161
- srcDoc = { attribs . srcdoc }
162
- width = { attribs . width }
163
- height = { attribs . height }
164
- sandbox = "allow-forms allow-scripts allow-same-origin"
165
- />
166
- ) ;
167
- }
168
128
169
129
if ( noSanitize && urlTransform != null && attribs != null ) {
170
130
// since we did not sanitize the HTML (which also does urlTransform),
0 commit comments