##// END OF EJS Templates
don't populate sanitized.safe by default...
MinRK -
Show More
@@ -1,120 +1,122 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2014 The IPython Development Team
2 // Copyright (C) 2014 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // Utilities
9 // Utilities
10 //============================================================================
10 //============================================================================
11 IPython.namespace('IPython.security');
11 IPython.namespace('IPython.security');
12
12
13 IPython.security = (function (IPython) {
13 IPython.security = (function (IPython) {
14 "use strict";
14 "use strict";
15
15
16 var utils = IPython.utils;
16 var utils = IPython.utils;
17
17
18 var noop = function (x) { return x; };
18 var noop = function (x) { return x; };
19
19
20 var cmp_tree = function (a, b) {
20 var cmp_tree = function (a, b) {
21 // compare two HTML trees
21 // compare two HTML trees
22 // only checks the tag structure is preserved,
22 // only checks the tag structure is preserved,
23 // not any attributes or contents
23 // not any attributes or contents
24 if (a.length !== b.length) {
24 if (a.length !== b.length) {
25 return false;
25 return false;
26 }
26 }
27
27
28 for (var i = a.length - 1; i >= 0; i--) {
28 for (var i = a.length - 1; i >= 0; i--) {
29 if (a[i].tagName && b[i].tagName && a[i].tagName.toLowerCase() != b[i].tagName.toLowerCase()) {
29 if (a[i].tagName && b[i].tagName && a[i].tagName.toLowerCase() != b[i].tagName.toLowerCase()) {
30 return false;
30 return false;
31 }
31 }
32 }
32 }
33 var ac = a.children();
33 var ac = a.children();
34 var bc = b.children();
34 var bc = b.children();
35 if (ac.length === 0 && bc.length === 0) {
35 if (ac.length === 0 && bc.length === 0) {
36 return true;
36 return true;
37 }
37 }
38 return cmp_tree(ac, bc);
38 return cmp_tree(ac, bc);
39 };
39 };
40
40
41 var caja;
41 var caja;
42 if (window && window.html) {
42 if (window && window.html) {
43 caja = window.html;
43 caja = window.html;
44 caja.html4 = window.html4;
44 caja.html4 = window.html4;
45 }
45 }
46
46
47 var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
47 var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
48 // wrap sanitizeAttribs into trusting data-attributes
48 // wrap sanitizeAttribs into trusting data-attributes
49 var ATTRIBS = caja.html4.ATTRIBS;
49 var ATTRIBS = caja.html4.ATTRIBS;
50 for (var i = 0; i < attribs.length; i += 2) {
50 for (var i = 0; i < attribs.length; i += 2) {
51 var attribName = attribs[i];
51 var attribName = attribs[i];
52 if (attribName.substr(0,5) == 'data-') {
52 if (attribName.substr(0,5) == 'data-') {
53 var attribKey = '*::' + attribName;
53 var attribKey = '*::' + attribName;
54 if (!ATTRIBS.hasOwnProperty(attribKey)) {
54 if (!ATTRIBS.hasOwnProperty(attribKey)) {
55 ATTRIBS[attribKey] = 0;
55 ATTRIBS[attribKey] = 0;
56 }
56 }
57 }
57 }
58 }
58 }
59 return caja.sanitizeAttribs(tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger);
59 return caja.sanitizeAttribs(tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger);
60 };
60 };
61
61
62 var sanitize = function (html, log) {
62 var sanitize = function (html, log) {
63 // sanitize HTML
63 // sanitize HTML
64 // returns a struct of
64 // returns a struct of
65 // {
65 // {
66 // src: original_html,
66 // src: original_html,
67 // sanitized: the_sanitized_html,
67 // sanitized: the_sanitized_html,
68 // safe: bool // false if the sanitizer made any changes
68 // safe: bool // false if the sanitizer made any changes
69 // }
69 // }
70 var result = {
70 var result = {
71 src : html,
71 src : html,
72 safe : true
72 safe : true
73 };
73 };
74 var record_messages = function (msg, opts) {
74 var record_messages = function (msg, opts) {
75 console.log("HTML Sanitizer", msg, opts);
75 console.log("HTML Sanitizer", msg, opts);
76 result.safe = false;
76 result.safe = false;
77 };
77 };
78
78
79 var html4 = caja.html4;
79 var html4 = caja.html4;
80 var policy = function (tagName, attribs) {
80 var policy = function (tagName, attribs) {
81 if (!(html4.ELEMENTS[tagName] & html4.eflags.UNSAFE)) {
81 if (!(html4.ELEMENTS[tagName] & html4.eflags.UNSAFE)) {
82 return {
82 return {
83 'attribs': sanitizeAttribs(tagName, attribs,
83 'attribs': sanitizeAttribs(tagName, attribs,
84 noop, noop, record_messages)
84 noop, noop, record_messages)
85 };
85 };
86 } else {
86 } else {
87 record_messages(tagName + " removed", {
87 record_messages(tagName + " removed", {
88 change: "removed",
88 change: "removed",
89 tagName: tagName
89 tagName: tagName
90 });
90 });
91 }
91 }
92 };
92 };
93
93
94 result.sanitized = caja.sanitizeWithPolicy(html, policy);
94 result.sanitized = caja.sanitizeWithPolicy(html, policy);
95 // caja can strip whole elements without logging,
96 // so double-check that node structure didn't change
97 if (result.safe) {
98 result.safe = cmp_tree($(result.sanitized), $(result.src));
99 }
100 return result;
95 return result;
101 };
96 };
102
97
103 var sanitize_html = function (html) {
98 var sanitize_html = function (html) {
104 // shorthand for str-to-str conversion, dropping the struct
99 // shorthand for str-to-str conversion, dropping the struct
105 return sanitize(html).sanitized;
100 return sanitize(html).sanitized;
106 };
101 };
107
102
108 var is_safe = function (html) {
103 var is_safe = function (html) {
109 // just return bool for whether an HTML string is safe
104 // just return bool for whether an HTML string is safe
110 return sanitize(html).safe;
105 var result = sanitize(html);
106
107 // caja can strip whole elements without logging,
108 // so double-check that node structure didn't change
109 if (result.safe) {
110 result.safe = cmp_tree($(result.sanitized), $(html));
111 }
112 return result.safe;
111 };
113 };
112
114
113 return {
115 return {
114 is_safe: is_safe,
116 is_safe: is_safe,
115 sanitize: sanitize,
117 sanitize: sanitize,
116 sanitize_html: sanitize_html
118 sanitize_html: sanitize_html
117 };
119 };
118
120
119 }(IPython));
121 }(IPython));
120
122
General Comments 0
You need to be logged in to leave comments. Login now