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

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