Disable jQuery prefilter specifically to parse sanitized HTML (#29)

* Add and use sanitize_html_and_parse() function

* Describe return type in doc comment

* Reset htmlPrefilter even if parsing HTML fails

* Return directly from try block

* Move toinsert to inner scope
This commit is contained in:
Thomas Kluyver 2018-03-18 08:00:12 +00:00 committed by GitHub
parent 97dd1ed9f3
commit 4e79ebb49a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 7 deletions

View File

@ -122,9 +122,29 @@ define([
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
};

View File

@ -674,19 +674,23 @@ define([
var type = OutputArea.display_order[i];
var append = OutputArea.append_map[type];
if ((json.data[type] !== undefined) && append) {
var md = json.metadata || {};
var value = json.data[type];
var toinsert;
if (!this.trusted && !OutputArea.safe_outputs[type]) {
// not trusted, sanitize HTML
if (type===MIME_HTML || type==='text/svg') {
value = security.sanitize_html(value);
var parsed = $(security.sanitize_html_and_parse(value));
toinsert = append.apply(this, [parsed, md, element, handle_inserted]);
} else {
// don't display if we don't know how to sanitize it
console.log("Ignoring untrusted " + type + " output.");
continue;
}
} else {
toinsert = append.apply(this, [value, md, element, handle_inserted]);
}
var md = json.metadata || {};
var toinsert = append.apply(this, [value, md, element, handle_inserted]);
// Since only the png and jpeg mime types call the inserted
// callback, if the mime type is something other we must call the
// inserted callback only when the element is actually inserted

View File

@ -248,8 +248,7 @@ define([
// HTML <img>)
var text = this.get_text();
marked(text, function (err, html) {
html = security.sanitize_html(html);
html = $($.parseHTML(html));
html = $(security.sanitize_html_and_parse(html));
html.find('img[src^="attachment:"]').each(function (i, h) {
h = $(h);
var key = h.attr('src').replace(/^attachment:/, '');
@ -402,8 +401,7 @@ define([
};
marked(text, { renderer: renderer }, function (err, html) {
html = mathjaxutils.replace_math(html, math);
html = security.sanitize_html(html);
html = $($.parseHTML(html));
html = $(security.sanitize_html_and_parse(html));
// add anchors to headings
html.find(":header").addBack(":header").each(function (i, h) {
h = $(h);