Skip to content

Commit 0e52fd8

Browse files
committed
migrate google-caja to npm
1 parent 4ecb78e commit 0e52fd8

File tree

7 files changed

+133
-18
lines changed

7 files changed

+133
-18
lines changed

nbclassic/static/base/js/security.js

Lines changed: 109 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,124 @@
33

44
define([
55
'jquery',
6-
'components/sanitizer/index',
7-
], function($, sanitizer) {
6+
'components/google-caja-sanitizer/sanitizer',
7+
], function($, sanitize) {
88
"use strict";
99

1010
var noop = function (x) { return x; };
11-
var defaultSanitizer = sanitizer.defaultSanitizer;
11+
12+
var caja;
13+
if (window && window.html) {
14+
caja = window.html;
15+
caja.html4 = window.html4;
16+
caja.sanitizeStylesheet = window.sanitizeStylesheet;
17+
}
18+
19+
var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
20+
/**
21+
* add trusting data-attributes to the default sanitizeAttribs from caja
22+
* this function is mostly copied from the caja source
23+
*/
24+
var ATTRIBS = caja.html4.ATTRIBS;
25+
for (var i = 0; i < attribs.length; i += 2) {
26+
var attribName = attribs[i];
27+
if (attribName.substr(0,5) == 'data-') {
28+
var attribKey = '*::' + attribName;
29+
if (!ATTRIBS.hasOwnProperty(attribKey)) {
30+
ATTRIBS[attribKey] = 0;
31+
}
32+
}
33+
}
34+
// Caja doesn't allow data uri for img::src, see
35+
// https://github.com/google/caja/issues/1558
36+
// This is not a security issue for browser post ie6 though, so we
37+
// disable the check
38+
// https://www.owasp.org/index.php/Script_in_IMG_tags
39+
ATTRIBS['img::src'] = 0;
40+
return caja.sanitizeAttribs(tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger);
41+
};
42+
43+
var sanitize_css = function (css, tagPolicy) {
44+
/**
45+
* sanitize CSS
46+
* like sanitize_html, but for CSS
47+
* called by sanitize_stylesheets
48+
*/
49+
return caja.sanitizeStylesheet(
50+
window.location.pathname,
51+
css,
52+
{
53+
containerClass: null,
54+
idSuffix: '',
55+
tagPolicy: tagPolicy,
56+
virtualizeAttrName: noop
57+
},
58+
noop
59+
);
60+
};
61+
62+
var sanitize_stylesheets = function (html, tagPolicy) {
63+
/**
64+
* sanitize just the css in style tags in a block of html
65+
* called by sanitize_html, if allow_css is true
66+
*/
67+
var h = $("<div/>").append(html);
68+
var style_tags = h.find("style");
69+
if (!style_tags.length) {
70+
// no style tags to sanitize
71+
return html;
72+
}
73+
style_tags.each(function(i, style) {
74+
style.innerHTML = sanitize_css(style.innerHTML, tagPolicy);
75+
});
76+
return h.html();
77+
};
1278

1379
var sanitize_html = function (html, allow_css) {
1480
/**
1581
* sanitize HTML
1682
* if allow_css is true (default: false), CSS is sanitized as well.
1783
* otherwise, CSS elements and attributes are simply removed.
1884
*/
19-
const options = {};
20-
if (!allow_css) {
21-
options.allowedStyles = {};
22-
}
23-
return defaultSanitizer.sanitize(html, options);
85+
var html4 = caja.html4;
86+
87+
if (allow_css) {
88+
// allow sanitization of style tags,
89+
// not just scrubbing
90+
html4.ELEMENTS.style &= ~html4.eflags.UNSAFE;
91+
html4.ATTRIBS.style = html4.atype.STYLE;
92+
} else {
93+
// scrub all CSS
94+
html4.ELEMENTS.style |= html4.eflags.UNSAFE;
95+
html4.ATTRIBS.style = html4.atype.SCRIPT;
96+
}
97+
98+
var record_messages = function (msg, opts) {
99+
console.log("HTML Sanitizer", msg, opts);
100+
};
101+
102+
var policy = function (tagName, attribs) {
103+
if (!(html4.ELEMENTS[tagName] & html4.eflags.UNSAFE)) {
104+
return {
105+
'attribs': sanitizeAttribs(tagName, attribs,
106+
noop, noop, record_messages)
107+
};
108+
} else {
109+
record_messages(tagName + " removed", {
110+
change: "removed",
111+
tagName: tagName
112+
});
113+
}
114+
};
115+
116+
var sanitized = caja.sanitizeWithPolicy(html, policy);
117+
118+
if (allow_css) {
119+
// sanitize style tags as stylesheets
120+
sanitized = sanitize_stylesheets(sanitized, policy);
121+
}
122+
123+
return sanitized;
24124
};
25125

26126
var sanitize_html_and_parse = function (html, allow_css) {
@@ -43,6 +143,7 @@ define([
43143
};
44144

45145
var security = {
146+
caja: caja,
46147
sanitize_html_and_parse: sanitize_html_and_parse,
47148
sanitize_html: sanitize_html
48149
};

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"watch:css": "onchange 'nbclassic/static/**/*.less' -- npm run build:css",
3535
"watch:js": "onchange 'nbclassic/static/**/!(*.min).js' 'bower.json' -- npm run build:js",
3636
"watch": "npm-run-all --parallel watch:*",
37-
"postinstall": "node postinstall.js"
37+
"postinstall": "node postinstall.js && npx patch-package google-caja-sanitizer"
3838
},
3939
"devDependencies": {
4040
"@babel/core": "^7.15.0",
@@ -63,7 +63,7 @@
6363
"mathjax": "^2.7.4",
6464
"codemirror": "~5.58.2",
6565
"es6-promise": "~1.0",
66-
"@bower_components/google-caja": "https://github.com/minrk/google-caja-bower/archive/refs/tags/5669.0.0.tar.gz",
66+
"google-caja-sanitizer": "~1.0.4",
6767
"jed": "~1.1.1",
6868
"jquery": "~3.7.1",
6969
"jquery-typeahead": "~2.11.1",

postinstall.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ ensureSymlink(
9898
ensureSymlink(
9999
"node_modules/codemirror",
100100
"nbclassic/static/components/codemirror"
101-
);
101+
);
102102
ensureSymlink(
103103
"node_modules/react",
104104
"nbclassic/static/components/react"
@@ -123,3 +123,7 @@ ensureSymlink(
123123
"node_modules/requirejs-text",
124124
"nbclassic/static/components/requirejs-text"
125125
);
126+
ensureSymlink(
127+
"node_modules/google-caja-sanitizer",
128+
"nbclassic/static/components/google-caja-sanitizer"
129+
);

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ artifacts = [
129129
"nbclassic/static/components/bootstrap-tour/build/js/bootstrap-tour.min.js" = "nbclassic/static/components/bootstrap-tour/build/js/bootstrap-tour.min.js"
130130
"nbclassic/static/components/bootstrap/dist/js/bootstrap.min.js" = "nbclassic/static/components/bootstrap/dist/js/bootstrap.min.js"
131131
"nbclassic/static/components/create-react-class/index.js" = "nbclassic/static/components/create-react-class/index.js"
132-
"nbclassic/static/components/google-caja/html-css-sanitizer-minified.js" = "nbclassic/static/components/google-caja/html-css-sanitizer-minified.js"
132+
"nbclassic/static/components/google-caja-sanitizer/sanitizer.js" = "nbclassic/static/components/google-caja-sanitizer/sanitizer.js"
133133
"nbclassic/static/components/jed/jed.js" = "nbclassic/static/components/jed/jed.js"
134134
"nbclassic/static/components/jquery/dist/jquery.min.js" = "nbclassic/static/components/jquery/dist/jquery.min.js"
135135
"nbclassic/static/components/jquery-typeahead/dist/jquery.typeahead.min.js" = "nbclassic/static/components/jquery-typeahead/dist/jquery.typeahead.min.js"

tools/security_deprecated.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
define([
55
'jquery',
6-
'components/google-caja/html-css-sanitizer-minified',
6+
'components/google-caja-sanitizer/sanitizer',
77
], function($, sanitize) {
88
"use strict";
99

webpack.config.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const path = require('path');
22
const crypto = require('crypto');
3+
const webpack = require('webpack');
4+
35

46
// Workaround for loaders using "md4" by default, which is not supported in FIPS-compliant OpenSSL
57
// See https://github.com/jupyterlab/jupyterlab/issues/11248
@@ -30,5 +32,12 @@ module.exports = {
3032
}
3133
}
3234
]
33-
}
35+
},
36+
plugins: [
37+
new webpack.BannerPlugin({
38+
banner: 'var exports = {};',
39+
raw: true,
40+
entryOnly: true,
41+
}),
42+
],
3443
}

yarn.lock

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -841,10 +841,6 @@
841841
classnames "^2.2"
842842
tslib "~2.3.1"
843843

844-
"@bower_components/google-caja@https://github.com/minrk/google-caja-bower/archive/refs/tags/5669.0.0.tar.gz":
845-
version "0.0.0"
846-
resolved "https://github.com/minrk/google-caja-bower/archive/refs/tags/5669.0.0.tar.gz#6830582db17ef8087e38d3aa9703966fb9a86278"
847-
848844
"@discoveryjs/json-ext@^0.5.0":
849845
version "0.5.7"
850846
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
@@ -2077,6 +2073,11 @@ globals@^11.1.0:
20772073
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
20782074
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
20792075

2076+
google-caja-sanitizer@~1.0.4:
2077+
version "1.0.4"
2078+
resolved "https://registry.yarnpkg.com/google-caja-sanitizer/-/google-caja-sanitizer-1.0.4.tgz#614cf2c3d2e5e83ea961ab98d79318c03d8682e5"
2079+
integrity sha512-KEqGmAIbxvEZy4nPLpVoAlxQhEoq4H/0WMEQsEXlxjP+OxCT9nDYQi7Z7PVanwb77Jc+OJ9SoBQ6zw2OnmCvLw==
2080+
20802081
gopd@^1.0.1, gopd@^1.2.0:
20812082
version "1.2.0"
20822083
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"

0 commit comments

Comments
 (0)