##// END OF EJS Templates
sanitize CSS...
MinRK -
Show More
@@ -42,6 +42,7 b' IPython.security = (function (IPython) {'
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 caja.sanitizeStylesheet = window.sanitizeStylesheet;
45 }
46 }
46
47
47 var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
48 var sanitizeAttribs = function (tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger) {
@@ -59,8 +60,37 b' IPython.security = (function (IPython) {'
59 return caja.sanitizeAttribs(tagName, attribs, opt_naiveUriRewriter, opt_nmTokenPolicy, opt_logger);
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 // sanitize HTML
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 // returns a struct of
94 // returns a struct of
65 // {
95 // {
66 // src: original_html,
96 // src: original_html,
@@ -69,6 +99,20 b' IPython.security = (function (IPython) {'
69 // This is an incomplete indication,
99 // This is an incomplete indication,
70 // only used to indicate whether further verification is necessary.
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 var result = {
116 var result = {
73 src : html,
117 src : html,
74 _maybe_safe : true
118 _maybe_safe : true
@@ -78,7 +122,6 b' IPython.security = (function (IPython) {'
78 result._maybe_safe = false;
122 result._maybe_safe = false;
79 };
123 };
80
124
81 var html4 = caja.html4;
82 var policy = function (tagName, attribs) {
125 var policy = function (tagName, attribs) {
83 if (!(html4.ELEMENTS[tagName] & html4.eflags.UNSAFE)) {
126 if (!(html4.ELEMENTS[tagName] & html4.eflags.UNSAFE)) {
84 return {
127 return {
@@ -94,6 +137,12 b' IPython.security = (function (IPython) {'
94 };
137 };
95
138
96 result.sanitized = caja.sanitizeWithPolicy(html, policy);
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 return result;
146 return result;
98 };
147 };
99
148
@@ -104,6 +153,7 b' IPython.security = (function (IPython) {'
104
153
105 var is_safe = function (html) {
154 var is_safe = function (html) {
106 // just return bool for whether an HTML string is safe
155 // just return bool for whether an HTML string is safe
156 // this is not currently used for anything other than tests.
107 var result = sanitize(html);
157 var result = sanitize(html);
108
158
109 // caja can strip whole elements without logging,
159 // caja can strip whole elements without logging,
@@ -117,6 +167,7 b' IPython.security = (function (IPython) {'
117 };
167 };
118
168
119 return {
169 return {
170 caja: caja,
120 is_safe: is_safe,
171 is_safe: is_safe,
121 sanitize: sanitize,
172 sanitize: sanitize,
122 sanitize_html: sanitize_html
173 sanitize_html: sanitize_html
@@ -291,7 +291,7 b' class="notebook_app"'
291
291
292 {{super()}}
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 <script src="{{ static_url("components/codemirror/lib/codemirror.js") }}" charset="utf-8"></script>
295 <script src="{{ static_url("components/codemirror/lib/codemirror.js") }}" charset="utf-8"></script>
296 <script type="text/javascript">
296 <script type="text/javascript">
297 CodeMirror.modeURL = "{{ static_url("components/codemirror/mode/%N/%N.js", include_version=False) }}";
297 CodeMirror.modeURL = "{{ static_url("components/codemirror/mode/%N/%N.js", include_version=False) }}";
@@ -3,6 +3,7 b' safe_tests = ['
3 '<h1 class="foo">Hi There!</h1>',
3 '<h1 class="foo">Hi There!</h1>',
4 '<a data-cite="foo">citation</a>',
4 '<a data-cite="foo">citation</a>',
5 '<div><span>Hi There</span></div>',
5 '<div><span>Hi There</span></div>',
6 '<style>div.foo { background: #ffff; }</style>',
6 ];
7 ];
7
8
8 unsafe_tests = [
9 unsafe_tests = [
@@ -17,7 +18,7 b' unsafe_tests = ['
17 '<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert(999);">',
18 '<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert(999);">',
18 '<IFRAME SRC="javascript:alert(999);"></IFRAME>',
19 '<IFRAME SRC="javascript:alert(999);"></IFRAME>',
19 '<IFRAME SRC=# onmouseover="alert(document.cookie)"></IFRAME>',
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 '<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>',
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 var is_safe = self.evaluate(function (item) {
27 var is_safe = self.evaluate(function (item) {
27 return IPython.security.is_safe(item);
28 return IPython.security.is_safe(item);
28 }, item);
29 }, item);
30 var sanitized = self.evaluate(function (item) {
31 return IPython.security.sanitize_html(item);
32 }, item);
33
29 this.test.assert(is_safe, "Safe: " + item);
34 this.test.assert(is_safe, "Safe: " + item);
30 });
35 });
31 this.each(unsafe_tests, function (self, item) {
36 this.each(unsafe_tests, function (self, item) {
General Comments 0
You need to be logged in to leave comments. Login now