connect-src-self.sub.js (4756B)
1 importScripts("{{location[server]}}/resources/testharness.js"); 2 importScripts("{{location[server]}}/content-security-policy/support/testharness-helper.js"); 3 4 let base_same_origin_url = 5 "{{location[server]}}/content-security-policy/support/resource.py"; 6 let base_cross_origin_url = 7 "https://{{hosts[][www]}}:{{ports[https][1]}}" + 8 "/content-security-policy/support/resource.py"; 9 10 // Same-origin 11 promise_test(t => { 12 let url = `${base_same_origin_url}?same-origin-fetch`; 13 assert_no_csp_event_for_url(t, url); 14 15 return fetch(url) 16 .then(t.step_func(r => assert_equals(r.status, 200))); 17 }, "Same-origin 'fetch()' in " + self.location.protocol + 18 " with {{GET[test-name]}}"); 19 20 // XHR is not available in service workers. 21 if (self.XMLHttpRequest) { 22 promise_test(t => { 23 let url = `${base_same_origin_url}?same-origin-xhr`; 24 assert_no_csp_event_for_url(t, url); 25 26 return new Promise((resolve, reject) => { 27 let xhr = new XMLHttpRequest(); 28 xhr.open("GET", url); 29 xhr.onload = resolve; 30 xhr.onerror = _ => reject("xhr.open should success."); 31 xhr.send(); 32 }); 33 }, "Same-origin XHR in " + self.location.protocol + 34 " with {{GET[test-name]}}"); 35 } 36 37 let fetch_cross_origin_url = `${base_cross_origin_url}?cross-origin-fetch`; 38 39 // Cross-origin 40 promise_test(t => { 41 let url = fetch_cross_origin_url; 42 43 return Promise.all([ 44 waitUntilCSPEventForURL(t, url), 45 fetch(url) 46 .then(t.step_func(_ => assert_unreached( 47 "cross-origin fetch should have thrown."))) 48 .catch(t.step_func(e => assert_true(e instanceof TypeError))) 49 ]); 50 }, "Cross-origin 'fetch()' in " + self.location.protocol + 51 " with {{GET[test-name]}}"); 52 53 let xhr_cross_origin_url = `${base_cross_origin_url}?cross-origin-xhr`; 54 55 // XHR is not available in service workers. 56 if (self.XMLHttpRequest) { 57 promise_test(t => { 58 let url = xhr_cross_origin_url; 59 60 return Promise.all([ 61 waitUntilCSPEventForURL(t, url), 62 new Promise((resolve, reject) => { 63 let xhr = new XMLHttpRequest(); 64 xhr.open("GET", url); 65 xhr.onload = _ => reject("xhr.open should have thrown."); 66 xhr.onerror = resolve; 67 xhr.send(); 68 }) 69 ]); 70 }, "Cross-origin XHR in " + self.location.protocol + 71 " with {{GET[test-name]}}"); 72 } 73 74 let redirect_url = `{{location[server]}}/common/redirect-opt-in.py?` + 75 `status=307&location=${fetch_cross_origin_url}`; 76 77 // Same-origin redirecting to cross-origin 78 promise_test(t => { 79 let url = redirect_url; 80 81 return Promise.all([ 82 waitUntilCSPEventForURL(t, url), 83 fetch(url) 84 .then(t.step_func(_ => assert_unreached( 85 "cross-origin redirect should have thrown."))) 86 .catch(t.step_func(e => assert_true(e instanceof TypeError))) 87 ]); 88 }, "Same-origin => cross-origin 'fetch()' in " + self.location.protocol + 89 " with {{GET[test-name]}}"); 90 91 92 let websocket_url = "wss://{{host}}:{{ports[wss][0]}}/echo"; 93 94 // The WebSocket URL is not the same as 'self' 95 promise_test(t => { 96 return Promise.all([ 97 waitUntilCSPEventForURL(t, websocket_url), 98 new Promise((resolve, reject) => { 99 // Firefox throws in the constructor, Chrome triggers the error event. 100 try { 101 let ws = new WebSocket(websocket_url); 102 ws.onerror = resolve; 103 ws.onopen = reject; // unexpected 104 } catch (e) { 105 resolve(); 106 } 107 }) 108 ]); 109 }, "WebSocket in " + self.location.protocol + " with {{GET[test-name]}}"); 110 111 let expected_blocked_urls = self.XMLHttpRequest 112 ? [ fetch_cross_origin_url, xhr_cross_origin_url, redirect_url, websocket_url ] 113 : [ fetch_cross_origin_url, redirect_url, websocket_url ]; 114 115 promise_test(async t => { 116 let report_url = `{{location[server]}}/reporting/resources/report.py` + 117 `?op=retrieve_report&reportID={{GET[id]}}` + 118 `&min_count=${expected_blocked_urls.length}`; 119 120 let response = await fetch(report_url); 121 assert_equals(response.status, 200, "Fetching reports failed"); 122 123 let response_json = await response.json(); 124 let reports = response_json.map(x => x["csp-report"]); 125 126 assert_array_equals( 127 reports.map(x => x["blocked-uri"]).sort(), 128 expected_blocked_urls.sort(), 129 "Reports do not match"); 130 reports.forEach(x => { 131 assert_equals( 132 x["violated-directive"], "connect-src", 133 "Violated directive in report does not match"); 134 assert_equals( 135 x["effective-directive"], "connect-src", 136 "Effective directive in report does not match"); 137 assert_equals( 138 x["disposition"], "enforce", 139 "Effective directive in report does not match"); 140 }); 141 }, "Reports match in " + self.location.protocol + " with {{GET[test-name]}}"); 142 143 done();