Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ jobs:
restore-keys: |
${{ runner.os }}-pip-${{ matrix.python }}

- name: Temporary workaround for sanitizer loading in JS Tests
run: |
cp tools/security_deprecated.js notebook/static/base/js/security.js

- name: Install dependencies
run: |
pip install --upgrade pip
Expand Down
1 change: 1 addition & 0 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"create-react-class": "https://cdn.jsdelivr.net/npm/[email protected]/create-react-class.min.js",
"es6-promise": "~1.0",
"font-awesome": "components/font-awesome#~4.7.0",
"google-caja": "5669",
"jed": "~1.1.1",
"jquery": "components/jquery#~3.5.0",
"jquery-typeahead": "~2.10.6",
Expand Down
1 change: 1 addition & 0 deletions setupbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ def find_package_data():
pjoin(components, "bootstrap-tour", "build", "js", "bootstrap-tour.min.js"),
pjoin(components, "create-react-class", "index.js"),
pjoin(components, "font-awesome", "css", "*.css"),
pjoin(components, "google-caja", "html-css-sanitizer-minified.js"),
pjoin(components, "es6-promise", "*.js"),
pjoin(components, "font-awesome", "fonts", "*.*"),
pjoin(components, "jed", "jed.js"),
Expand Down
152 changes: 152 additions & 0 deletions tools/security_deprecated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

define([
'jquery',
'components/google-caja/html-css-sanitizer-minified',
], function($, sanitize) {
"use strict";

var noop = function (x) { return x; };

var caja;
if (window && window.html) {
caja = window.html;
caja.html4 = window.html4;
caja.sanitizeStylesheet = window.sanitizeStylesheet;
}

var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
/**
* add trusting data-attributes to the default sanitizeAttribs from caja
* this function is mostly copied from the caja source
*/
var ATTRIBS = caja.html4.ATTRIBS;
for (var i = 0; i < attribs.length; i += 2) {
var attribName = attribs[i];
if (attribName.substr(0,5) == 'data-') {
var attribKey = '*::' + attribName;
if (!ATTRIBS.hasOwnProperty(attribKey)) {
ATTRIBS[attribKey] = 0;
}
}
}
// Caja doesn't allow data uri for img::src, see
// https://github.com/google/caja/issues/1558
// This is not a security issue for browser post ie6 though, so we
// disable the check
// https://www.owasp.org/index.php/Script_in_IMG_tags
ATTRIBS['img::src'] = 0;
return caja.sanitizeAttribs(tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger);
};

var sanitize_css = function (css, tagPolicy) {
/**
* sanitize CSS
* like sanitize_html, but for CSS
* called by sanitize_stylesheets
*/
return caja.sanitizeStylesheet(
window.location.pathname,
css,
{
containerClass: null,
idSuffix: '',
tagPolicy: tagPolicy,
virtualizeAttrName: noop
},
noop
);
};

var sanitize_stylesheets = function (html, tagPolicy) {
/**
* sanitize just the css in style tags in a block of html
* called by sanitize_html, if allow_css is true
*/
var h = $("<div/>").append(html);
var style_tags = h.find("style");
if (!style_tags.length) {
// no style tags to sanitize
return html;
}
style_tags.each(function(i, style) {
style.innerHTML = sanitize_css(style.innerHTML, tagPolicy);
});
return h.html();
};

var sanitize_html = function (html, allow_css) {
/**
* sanitize HTML
* if allow_css is true (default: false), CSS is sanitized as well.
* otherwise, CSS elements and attributes are simply removed.
*/
var html4 = caja.html4;

if (allow_css) {
// allow sanitization of style tags,
// not just scrubbing
html4.ELEMENTS.style &= ~html4.eflags.UNSAFE;
html4.ATTRIBS.style = html4.atype.STYLE;
} else {
// scrub all CSS
html4.ELEMENTS.style |= html4.eflags.UNSAFE;
html4.ATTRIBS.style = html4.atype.SCRIPT;
}

var record_messages = function (msg, opts) {
console.log("HTML Sanitizer", msg, opts);
};

var policy = function (tagName, attribs) {
if (!(html4.ELEMENTS[tagName] & html4.eflags.UNSAFE)) {
return {
'attribs': sanitizeAttribs(tagName, attribs,
noop, noop, record_messages)
};
} else {
record_messages(tagName + " removed", {
change: "removed",
tagName: tagName
});
}
};

var sanitized = caja.sanitizeWithPolicy(html, policy);

if (allow_css) {
// sanitize style tags as stylesheets
sanitized = sanitize_stylesheets(sanitized, policy);
}

return sanitized;
};

var sanitize_html_and_parse = function (html, allow_css) {
/**
* Sanitize HTML and parse it safely using jQuery.
*
* This disable's jQuery's html 'prefilter', which can make invalid
* HTML valid after the sanitizer has checked it.
*
* Returns an array of DOM nodes.
*/
var sanitized_html = sanitize_html(html, allow_css);
var prev_htmlPrefilter = $.htmlPrefilter;
$.htmlPrefilter = function(html) {return html;}; // Don't modify HTML
try {
return $.parseHTML(sanitized_html);
} finally {
$.htmlPrefilter = prev_htmlPrefilter; // Set it back again
}
};

var security = {
caja: caja,
sanitize_html_and_parse: sanitize_html_and_parse,
sanitize_html: sanitize_html
};

return security;
});