##// END OF EJS Templates
sanitize CSS...
MinRK -
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 (html, log) {
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/google-caja/html-sanitizer-minified.js") }}" charset="utf-8"></script>
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