Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: LayoutTests/http/tests/security/w3c/cross-origin-objects.html

Issue 1182073002: cross-origin: Adds W3C cross-origin security tests. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Added a link to the original test. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | LayoutTests/http/tests/security/w3c/cross-origin-objects-expected.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <!doctype html>
haraken 2015/06/12 15:13:16 Shall we add a TODO and mention our plan to fix th
Yuki 2015/06/15 10:06:03 Done.
2 <meta charset=utf-8>
3 <meta name="timeout" content="long">
4 <title>Cross-origin behavior of Window and Location</title>
5 <link rel="author" title="Bobby Holley (:bholley)" href="bobbyholley@gmail.com">
6 <link rel="help" href="https://html.spec.whatwg.org/multipage/#security-window">
7 <link rel="help" href="https://html.spec.whatwg.org/multipage/#security-location ">
8 // The original code lives at
9 // https://github.com/w3c/web-platform-tests/tree/master/html/browsers/origin/cr oss-origin-objects
10 <script>
11 // This test needs to run on 'web-platform.test:8000'.
12 if (document.location.hostname != "web-platform.test")
13 document.location = document.location.protocol + "//web-platform.test:8000" + document.location.pathname;
14 if (window.testRunner)
15 window.testRunner.setCanOpenWindows();
16 </script>
17 <script src="/resources/testharness.js"></script>
18 <script src="/resources/testharnessreport.js"></script>
19 <div id=log></div>
20 <iframe id="B"></iframe>
21 <iframe id="C"></iframe>
22 <script>
23
24 /*
25 * Setup boilerplate. This gives us a same-origin window "B" and a cross-origin
26 * window "C".
27 */
28
29 setup({explicit_done: true});
30 path = location.pathname.substring(0, location.pathname.lastIndexOf('/')) + '/re sources/frame.html';
31 var B = document.getElementById('B').contentWindow;
32 var C = document.getElementById('C').contentWindow;
33 B.frameElement.uriToLoad = path;
34 C.frameElement.uriToLoad = 'http://www1.web-platform.test:' + location.port + pa th;
35
36 function reloadSubframes(cb) {
37 var iframes = document.getElementsByTagName('iframe');
38 iframes.forEach = Array.prototype.forEach;
39 var count = 0;
40 function frameLoaded() {
41 this.onload = null;
42 if (++count == iframes.length)
43 cb();
44 }
45 iframes.forEach(function(ifr) { ifr.onload = frameLoaded; ifr.setAttribute('sr c', ifr.uriToLoad); });
46 }
47 function isObject(x) { return Object(x) === x; }
48
49 /*
50 * Note: we eschew assert_equals in a lot of these tests, since the harness ends
51 * up throwing when it tries to format a message involving a cross-origin object .
52 */
53
54 var testList = [];
55 function addTest(fun, desc) { testList.push([fun, desc]); }
56
57
58 /*
59 * Basic sanity testing.
60 */
61
62 addTest(function() {
63 assert_equals(location.host, 'web-platform.test:8000', 'Need to run the top-le vel test from web-platform.test:8000');
64 assert_equals(B.parent, window, "window.parent works same-origin");
65 assert_equals(C.parent, window, "window.parent works cross-origin");
66 assert_equals(B.location.pathname, path, "location.href works same-origin");
67 assert_throws(null, function() { C.location.pathname; }, "location.pathname th rows cross-origin");
68 assert_equals(B.frames, 'override', "Overrides visible in the same-origin case ");
69 assert_equals(C.frames, C, "Overrides invisible in the cross-origin case");
70 }, "Basic sanity-checking");
71
72 /*
73 * Whitelist behavior.
74 *
75 * Also tests for [[GetOwnProperty]] and [[HasOwnProperty]] behavior.
76 */
77
78 var whitelistedWindowProps = ['location', 'postMessage', 'window', 'frames', 'se lf', 'top', 'parent',
79 'opener', 'closed', 'close', 'blur', 'focus', 'len gth'];
80 addTest(function() {
81 for (var prop in window) {
82 if (whitelistedWindowProps.indexOf(prop) != -1) {
83 C[prop]; // Shouldn't throw.
84 Object.getOwnPropertyDescriptor(C, prop); // Shouldn't throw.
85 assert_true(Object.prototype.hasOwnProperty.call(C, prop), "hasOwnProperty for " + prop);
86 } else {
87 assert_throws(null, function() { C[prop]; }, "Should throw when accessing " + prop + " on Window");
88 assert_throws(null, function() { Object.getOwnPropertyDescriptor(C, prop); },
89 "Should throw when accessing property descriptor for " + pro p + " on Window");
90 assert_throws(null, function() { Object.prototype.hasOwnProperty.call(C, p rop); },
91 "Should throw when invoking hasOwnProperty for " + prop + " on Window");
92 }
93 if (prop != 'location')
94 assert_throws(null, function() { C[prop] = undefined; }, "Should throw whe n writing to " + prop + " on Window");
95 }
96 for (var prop in location) {
97 if (prop == 'replace') {
98 C.location[prop]; // Shouldn't throw.
99 Object.getOwnPropertyDescriptor(C.location, prop); // Shouldn't throw.
100 assert_true(Object.prototype.hasOwnProperty.call(C.location, prop), "hasOw nProperty for " + prop);
101 }
102 else {
103 assert_throws(null, function() { C[prop]; }, "Should throw when accessing " + prop + " on Location");
104 assert_throws(null, function() { Object.getOwnPropertyDescriptor(C, prop); },
105 "Should throw when accessing property descriptor for " + pro p + " on Location");
106 assert_throws(null, function() { Object.prototype.hasOwnProperty.call(C, p rop); },
107 "Should throw when invoking hasOwnProperty for " + prop + " on Location");
108 }
109 if (prop != 'href')
110 assert_throws(null, function() { C[prop] = undefined; }, "Should throw whe n writing to " + prop + " on Location");
111 }
112 }, "Only whitelisted properties are accessible cross-origin");
113
114 /*
115 * ES Internal Methods.
116 */
117
118 /*
119 * [[GetPrototypeOf]]
120 */
121 addTest(function() {
122 assert_true(Object.getPrototypeOf(C) === null, "cross-origin Window proto is n ull");
123 assert_true(Object.getPrototypeOf(C.location) === null, "cross-origin Location proto is null (__proto__)");
124 var protoGetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__ ').get;
125 assert_true(protoGetter.call(C) === null, "cross-origin Window proto is null") ;
126 assert_true(protoGetter.call(C.location) === null, "cross-origin Location prot o is null (__proto__)");
127 assert_throws(null, function() { C.__proto__; }, "__proto__ property not avail able cross-origin");
128 assert_throws(null, function() { C.location.__proto__; }, "__proto__ property not available cross-origin");
129
130 }, "[[GetPrototypeOf]] should return null");
131
132 /*
133 * [[SetPrototypeOf]]
134 */
135 addTest(function() {
136 assert_throws(null, function() { C.__proto__ = new Object(); }, "proto set on cross-origin Window");
137 assert_throws(null, function() { C.location.__proto__ = new Object(); }, "prot o set on cross-origin Location");
138 var setters = [Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'). set];
139 if (Object.setPrototypeOf)
140 setters.push(function(p) { Object.setPrototypeOf(this, p); });
141 setters.forEach(function(protoSetter) {
142 assert_throws(null, function() { protoSetter.call(C, new Object()); }, "prot o setter |call| on cross-origin Window");
143 assert_throws(null, function() { protoSetter.call(C.location, new Object()); }, "proto setter |call| on cross-origin Location");
144 });
145 }, "[[SetPrototypeOf]] should throw");
146
147 /*
148 * [[IsExtensible]]
149 */
150 addTest(function() {
151 assert_true(Object.isExtensible(C), "cross-origin Window should be extensible" );
152 assert_true(Object.isExtensible(C.location), "cross-origin Location should be extensible");
153 }, "[[IsExtensible]] should return true for cross-origin objects");
154
155 /*
156 * [[PreventExtensions]]
157 */
158 addTest(function() {
159 assert_throws(null, function() { Object.preventExtensions(C) },
160 "preventExtensions on cross-origin Window should throw");
161 assert_throws(null, function() { Object.preventExtensions(C.location) },
162 "preventExtensions on cross-origin Location should throw");
163 }, "[[PreventExtensions]] should throw for cross-origin objects");
164
165 /*
166 * [[GetOwnProperty]]
167 */
168
169 addTest(function() {
170 assert_true(isObject(Object.getOwnPropertyDescriptor(C, 'close')), "C.close is |own|");
171 assert_true(isObject(Object.getOwnPropertyDescriptor(C, 'top')), "C.top is |ow n|");
172 assert_true(isObject(Object.getOwnPropertyDescriptor(C.location, 'href')), "C. location.href is |own|");
173 assert_true(isObject(Object.getOwnPropertyDescriptor(C.location, 'replace')), "C.location.replace is |own|");
174 }, "[[GetOwnProperty]] - Properties on cross-origin objects should be reported | own|");
175
176 function checkPropertyDescriptor(desc, propName, expectWritable) {
177 assert_true(isObject(desc), "property descriptor for " + propName + " should e xist");
178 assert_equals(desc.enumerable, false, "property descriptor for " + propName + " should be non-enumerable");
179 assert_equals(desc.configurable, true, "property descriptor for " + propName + " should be configurable");
180 if ('value' in desc)
181 assert_equals(desc.writable, expectWritable, "property descriptor for " + pr opName + " should have writable: " + expectWritable);
182 else
183 assert_equals(typeof desc.set != 'undefined', expectWritable,
184 "property descriptor for " + propName + " should " + (expectWr itable ? "" : "not ") + "have setter");
185 }
186
187 addTest(function() {
188 whitelistedWindowProps.forEach(function(prop) {
189 var desc = Object.getOwnPropertyDescriptor(C, prop);
190 checkPropertyDescriptor(desc, prop, prop == 'location');
191 });
192 checkPropertyDescriptor(Object.getOwnPropertyDescriptor(C.location, 'replace') , 'replace', false);
193 checkPropertyDescriptor(Object.getOwnPropertyDescriptor(C.location, 'href'), ' href', true);
194 assert_equals(typeof Object.getOwnPropertyDescriptor(C.location, 'href').get, 'undefined', "Cross-origin location should have no href getter");
195 }, "[[GetOwnProperty]] - Property descriptors for cross-origin properties should be set up correctly");
196
197 /*
198 * [[Delete]]
199 */
200 addTest(function() {
201 assert_throws(null, function() { delete C.location; }, "Can't delete cross-ori gin property");
202 assert_throws(null, function() { delete C.parent; }, "Can't delete cross-origi n property");
203 assert_throws(null, function() { delete C.length; }, "Can't delete cross-origi n property");
204 assert_throws(null, function() { delete C.document; }, "Can't delete cross-ori gin property");
205 assert_throws(null, function() { delete C.foopy; }, "Can't delete cross-origin property");
206 assert_throws(null, function() { delete C.location.href; }, "Can't delete cros s-origin property");
207 assert_throws(null, function() { delete C.location.replace; }, "Can't delete c ross-origin property");
208 assert_throws(null, function() { delete C.location.port; }, "Can't delete cros s-origin property");
209 assert_throws(null, function() { delete C.location.foopy; }, "Can't delete cro ss-origin property");
210 }, "[[Delete]] Should throw on cross-origin objects");
211
212 /*
213 * [[DefineOwnProperty]]
214 */
215 function checkDefine(obj, prop) {
216 var valueDesc = { configurable: true, enumerable: false, writable: false, valu e: 2 };
217 var accessorDesc = { configurable: true, enumerable: false, get: function() {} };
218 assert_throws(null, function() { Object.defineProperty(obj, prop, valueDesc); }, "Can't define cross-origin value property " + prop);
219 assert_throws(null, function() { Object.defineProperty(obj, prop, accessorDesc ); }, "Can't define cross-origin accessor property " + prop);
220 }
221 addTest(function() {
222 checkDefine(C, 'length');
223 checkDefine(C, 'parent');
224 checkDefine(C, 'location');
225 checkDefine(C, 'document');
226 checkDefine(C, 'foopy');
227 checkDefine(C.location, 'href');
228 checkDefine(C.location, 'replace');
229 checkDefine(C.location, 'port');
230 checkDefine(C.location, 'foopy');
231 }, "[[DefineOwnProperty]] Should throw for cross-origin objects");
232
233 /*
234 * [[Enumerate]]
235 */
236
237 addTest(function() {
238 for (var prop in C)
239 assert_unreached("Shouldn't have been able to enumerate " + prop + " on cros s-origin Window");
240 for (var prop in C.location)
241 assert_unreached("Shouldn't have been able to enumerate " + prop + " on cros s-origin Location");
242 }, "[[Enumerate]] should return an empty iterator");
243
244 /*
245 * [[OwnPropertyKeys]]
246 */
247
248 addTest(function() {
249 assert_array_equals(whitelistedWindowProps.sort(), Object.getOwnPropertyNames( C).sort(),
250 "Object.getOwnPropertyNames() gives the right answer for c ross-origin Window");
251 assert_array_equals(Object.getOwnPropertyNames(C.location).sort(), ['href', 'r eplace'],
252 "Object.getOwnPropertyNames() gives the right answer for c ross-origin Location");
253 }, "[[OwnPropertyKeys]] should return all properties from cross-origin objects") ;
254
255 addTest(function() {
256 assert_true(B.eval('parent.C') === C, "A and B observe the same identity for C 's Window");
257 assert_true(B.eval('parent.C.location') === C.location, "A and B observe the s ame identity for C's Location");
258 }, "A and B jointly observe the same identity for cross-origin Window and Locati on");
259
260 function checkFunction(f, proto) {
261 var name = f.name || '<missing name>';
262 assert_equals(typeof f, 'function', name + " is a function");
263 assert_equals(Object.getPrototypeOf(f), proto, f.name + " has the right protot ype");
264 }
265
266 addTest(function() {
267 checkFunction(C.close, Function.prototype);
268 checkFunction(C.location.replace, Function.prototype);
269 }, "Cross-origin functions get local Function.prototype");
270
271 addTest(function() {
272 assert_true(isObject(Object.getOwnPropertyDescriptor(C, 'parent')),
273 "Need to be able to use Object.getOwnPropertyDescriptor do this te st");
274 checkFunction(Object.getOwnPropertyDescriptor(C, 'parent').get, Function.proto type);
275 checkFunction(Object.getOwnPropertyDescriptor(C.location, 'href').set, Functio n.prototype);
276 }, "Cross-origin Window accessors get local Function.prototype");
277
278 addTest(function() {
279 checkFunction(close, Function.prototype);
280 assert_true(close != B.close, 'same-origin Window functions get their own obje ct');
281 assert_true(close != C.close, 'cross-origin Window functions get their own obj ect');
282 var close_B = B.eval('parent.C.close');
283 assert_true(close != close_B, 'close_B is unique when viewed by the parent');
284 assert_true(close_B != C.close, 'different Window functions per-incumbent scri pt settings object');
285 checkFunction(close_B, B.Function.prototype);
286
287 checkFunction(location.replace, Function.prototype);
288 assert_true(location.replace != C.location.replace, "cross-origin Location fun ctions get their own object");
289 var replace_B = B.eval('parent.C.location.replace');
290 assert_true(replace_B != C.location.replace, 'different Location functions per -incumbent script settings object');
291 checkFunction(replace_B, B.Function.prototype);
292 }, "Same-origin observers get different functions for cross-origin objects");
293
294 addTest(function() {
295 assert_true(isObject(Object.getOwnPropertyDescriptor(C, 'parent')),
296 "Need to be able to use Object.getOwnPropertyDescriptor do this te st");
297 var get_self_parent = Object.getOwnPropertyDescriptor(window, 'parent').get;
298 var get_parent_A = Object.getOwnPropertyDescriptor(C, 'parent').get;
299 var get_parent_B = B.eval('Object.getOwnPropertyDescriptor(parent.C, "parent") .get');
300 assert_true(get_self_parent != get_parent_A, 'different Window accessors per-i ncumbent script settings object');
301 assert_true(get_parent_A != get_parent_B, 'different Window accessors per-incu mbent script settings object');
302 checkFunction(get_self_parent, Function.prototype);
303 checkFunction(get_parent_A, Function.prototype);
304 checkFunction(get_parent_B, B.Function.prototype);
305 }, "Same-origin obsevers get different accessors for cross-origin Window");
306
307 addTest(function() {
308 var set_self_href = Object.getOwnPropertyDescriptor(window.location, 'href').s et;
309 var set_href_A = Object.getOwnPropertyDescriptor(C.location, 'href').set;
310 var set_href_B = B.eval('Object.getOwnPropertyDescriptor(parent.C.location, "h ref").set');
311 assert_true(set_self_href != set_href_A, 'different Location accessors per-inc umbent script settings object');
312 assert_true(set_href_A != set_href_B, 'different Location accessors per-incumb ent script settings object');
313 checkFunction(set_self_href, Function.prototype);
314 checkFunction(set_href_A, Function.prototype);
315 checkFunction(set_href_B, B.Function.prototype);
316 }, "Same-origin observers get different accessors for cross-origin Location");
317
318 function doDocumentDomainTest(cb) {
319 window.addEventListener('message', function onmessage(evt) {
320 window.removeEventListener('message', onmessage);
321 test(function() {
322 var results = evt.data;
323 assert_true(results.length > 0, 'Need results');
324 results.forEach(function(r) { assert_true(r.pass, r.message); });
325 }, "Cross-origin object identity preserved across document.domain");
326 win.close();
327 cb();
328 });
329 var win = window.open('resources/win-documentdomain.html');
330 }
331
332 // We do a fresh load of the subframes for each test to minimize side-effects.
333 // It would be nice to reload ourselves as well, but we can't do that without
334 // disrupting the test harness.
335 function runNextTest() {
336 var entry = testList.shift();
337 test(entry[0], entry[1]);
338 if (testList.length != 0)
339 reloadSubframes(runNextTest);
340 else
341 doDocumentDomainTest(done); // Asynchronous.
342 }
343 reloadSubframes(runNextTest);
344
345 </script>
OLDNEW
« no previous file with comments | « no previous file | LayoutTests/http/tests/security/w3c/cross-origin-objects-expected.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698