Show More
@@ -42,6 +42,7 b' IPython.security = (function (IPython) {' | |||
|
42 | 42 | if (window && window.html) { |
|
43 | 43 | caja = window.html; |
|
44 | 44 | caja.html4 = window.html4; |
|
45 | caja.sanitizeStylesheet = window.sanitizeStylesheet; | |
|
45 | 46 | } |
|
46 | 47 | |
|
47 | 48 | var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) { |
@@ -59,8 +60,37 b' IPython.security = (function (IPython) {' | |||
|
59 | 60 | return caja.sanitizeAttribs(tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger); |
|
60 | 61 | }; |
|
61 | 62 | |
|
62 |
var sanitize = function ( |
|
|
63 | var sanitize_css = function (css, tagPolicy) { | |
|
64 | return caja.sanitizeStylesheet( | |
|
65 | window.location.pathname, | |
|
66 | css, | |
|
67 | { | |
|
68 | containerClass: null, | |
|
69 | idSuffix: '', | |
|
70 | tagPolicy: tagPolicy, | |
|
71 | virtualizeAttrName: noop | |
|
72 | }, | |
|
73 | noop | |
|
74 | ); | |
|
75 | }; | |
|
76 | ||
|
77 | var sanitize_stylesheets = function (html, tagPolicy) { | |
|
78 | var h = $("<div/>").append(html); | |
|
79 | var style_tags = h.find("style"); | |
|
80 | if (!style_tags.length) { | |
|
81 | // no style tags to sanitize | |
|
82 | return html; | |
|
83 | } | |
|
84 | style_tags.each(function(i, style) { | |
|
85 | style.innerHTML = sanitize_css(style.innerHTML, tagPolicy); | |
|
86 | }); | |
|
87 | return h.html(); | |
|
88 | }; | |
|
89 | ||
|
90 | var sanitize = function (html, allow_css) { | |
|
63 | 91 | // sanitize HTML |
|
92 | // if allow_css is true (default), CSS is sanitized as well. | |
|
93 | // otherwise, CSS elements and attributes are simply removed. | |
|
64 | 94 | // returns a struct of |
|
65 | 95 | // { |
|
66 | 96 | // src: original_html, |
@@ -69,6 +99,20 b' IPython.security = (function (IPython) {' | |||
|
69 | 99 | // This is an incomplete indication, |
|
70 | 100 | // only used to indicate whether further verification is necessary. |
|
71 | 101 | // } |
|
102 | var html4 = caja.html4; | |
|
103 | ||
|
104 | if (allow_css === undefined) allow_css = true; | |
|
105 | if (allow_css) { | |
|
106 | // allow sanitization of style tags, | |
|
107 | // not just scrubbing | |
|
108 | html4.ELEMENTS.style &= ~html4.eflags.UNSAFE; | |
|
109 | html4.ATTRIBS.style = html4.atype.STYLE; | |
|
110 | } else { | |
|
111 | // scrub all CSS | |
|
112 | html4.ELEMENTS.style |= html4.eflags.UNSAFE; | |
|
113 | html4.ATTRIBS.style = html4.atype.SCRIPT; | |
|
114 | } | |
|
115 | ||
|
72 | 116 | var result = { |
|
73 | 117 | src : html, |
|
74 | 118 | _maybe_safe : true |
@@ -78,7 +122,6 b' IPython.security = (function (IPython) {' | |||
|
78 | 122 | result._maybe_safe = false; |
|
79 | 123 | }; |
|
80 | 124 | |
|
81 | var html4 = caja.html4; | |
|
82 | 125 | var policy = function (tagName, attribs) { |
|
83 | 126 | if (!(html4.ELEMENTS[tagName] & html4.eflags.UNSAFE)) { |
|
84 | 127 | return { |
@@ -92,8 +135,14 b' IPython.security = (function (IPython) {' | |||
|
92 | 135 | }); |
|
93 | 136 | } |
|
94 | 137 | }; |
|
95 | ||
|
138 | ||
|
96 | 139 | result.sanitized = caja.sanitizeWithPolicy(html, policy); |
|
140 | ||
|
141 | if (allow_css) { | |
|
142 | // sanitize style tags as stylesheets | |
|
143 | result.sanitized = sanitize_stylesheets(result.sanitized, policy); | |
|
144 | } | |
|
145 | ||
|
97 | 146 | return result; |
|
98 | 147 | }; |
|
99 | 148 | |
@@ -104,6 +153,7 b' IPython.security = (function (IPython) {' | |||
|
104 | 153 | |
|
105 | 154 | var is_safe = function (html) { |
|
106 | 155 | // just return bool for whether an HTML string is safe |
|
156 | // this is not currently used for anything other than tests. | |
|
107 | 157 | var result = sanitize(html); |
|
108 | 158 | |
|
109 | 159 | // caja can strip whole elements without logging, |
@@ -117,6 +167,7 b' IPython.security = (function (IPython) {' | |||
|
117 | 167 | }; |
|
118 | 168 | |
|
119 | 169 | return { |
|
170 | caja: caja, | |
|
120 | 171 | is_safe: is_safe, |
|
121 | 172 | sanitize: sanitize, |
|
122 | 173 | sanitize_html: sanitize_html |
@@ -291,7 +291,7 b' class="notebook_app"' | |||
|
291 | 291 | |
|
292 | 292 | {{super()}} |
|
293 | 293 | |
|
294 |
<script src="{{ static_url("components/google-caja/ |
|
|
294 | <script src="{{ static_url("components/google-caja/html-css-sanitizer-minified.js") }}" charset="utf-8"></script> | |
|
295 | 295 | <script src="{{ static_url("components/codemirror/lib/codemirror.js") }}" charset="utf-8"></script> |
|
296 | 296 | <script type="text/javascript"> |
|
297 | 297 | CodeMirror.modeURL = "{{ static_url("components/codemirror/mode/%N/%N.js", include_version=False) }}"; |
@@ -3,6 +3,7 b' safe_tests = [' | |||
|
3 | 3 | '<h1 class="foo">Hi There!</h1>', |
|
4 | 4 | '<a data-cite="foo">citation</a>', |
|
5 | 5 | '<div><span>Hi There</span></div>', |
|
6 | '<style>div.foo { background: #ffff; }</style>', | |
|
6 | 7 | ]; |
|
7 | 8 | |
|
8 | 9 | unsafe_tests = [ |
@@ -17,7 +18,7 b' unsafe_tests = [' | |||
|
17 | 18 | '<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert(999);">', |
|
18 | 19 | '<IFRAME SRC="javascript:alert(999);"></IFRAME>', |
|
19 | 20 | '<IFRAME SRC=# onmouseover="alert(document.cookie)"></IFRAME>', |
|
20 | '<style type="text/css">div.foo { background: #ffff; }</style>', | |
|
21 | '<style src="http://untrusted/style.css"></style>', | |
|
21 | 22 | '<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>', |
|
22 | 23 | ]; |
|
23 | 24 | |
@@ -26,6 +27,10 b' casper.notebook_test(function () {' | |||
|
26 | 27 | var is_safe = self.evaluate(function (item) { |
|
27 | 28 | return IPython.security.is_safe(item); |
|
28 | 29 | }, item); |
|
30 | var sanitized = self.evaluate(function (item) { | |
|
31 | return IPython.security.sanitize_html(item); | |
|
32 | }, item); | |
|
33 | ||
|
29 | 34 | this.test.assert(is_safe, "Safe: " + item); |
|
30 | 35 | }); |
|
31 | 36 | this.each(unsafe_tests, function (self, item) { |
General Comments 0
You need to be logged in to leave comments.
Login now