1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
<!DOCTYPE html>
<title>Service Worker: CSP control of fetch()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
<script>
function assert_resolves(promise, description) {
return promise.catch(function(reason) {
throw new Error(description + ' - ' + reason.message);
});
}
function assert_rejects(promise, description) {
return promise.then(
function() { throw new Error(description); },
function() {});
}
promise_test(function(t) {
var SCOPE = 'resources/fetch-csp-iframe.html';
var SCRIPT = 'resources/fetch-rewrite-worker.js';
var host_info = get_host_info();
var IMAGE_PATH =
base_path() + 'resources/fetch-access-control.py?PNGIMAGE';
var IMAGE_URL = host_info['HTTPS_ORIGIN'] + IMAGE_PATH;
var REMOTE_IMAGE_URL = host_info['HTTPS_REMOTE_ORIGIN'] + IMAGE_PATH;
var REDIRECT_URL =
host_info['HTTPS_ORIGIN'] + base_path() + 'resources/redirect.py';
var frame;
return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
.then(function(registration) {
t.add_cleanup(function() {
return service_worker_unregister(t, SCOPE);
});
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() {
return with_iframe(
SCOPE + '?' +
encodeURIComponent('img-src ' + host_info['HTTPS_ORIGIN'] +
'; script-src \'unsafe-inline\''));
})
.then(function(f) {
frame = f;
return assert_resolves(
frame.contentWindow.load_image(IMAGE_URL),
'Allowed scope image resource should be loaded.');
})
.then(function() {
return assert_rejects(
frame.contentWindow.load_image(REMOTE_IMAGE_URL),
'Disallowed scope image resource should not be loaded.');
})
.then(function() {
return assert_resolves(
frame.contentWindow.load_image(
// The request for IMAGE_URL will be fetched in SW.
'./sample?url=' + encodeURIComponent(IMAGE_URL)),
'Allowed scope image resource which was fetched via SW should ' +
'be loaded.');
})
.then(function() {
return assert_rejects(
frame.contentWindow.load_image(
// The request for REMOTE_IMAGE_URL will be fetched in SW.
'./sample?mode=no-cors&url=' +
encodeURIComponent(REMOTE_IMAGE_URL)),
'Disallowed scope image resource which was fetched via SW ' +
'should not be loaded.');
})
.then(function() {
frame.remove();
return with_iframe(
SCOPE + '?' +
encodeURIComponent(
'img-src ' + REDIRECT_URL +
'; script-src \'unsafe-inline\''));
})
.then(function(f) {
frame = f;
return assert_resolves(
frame.contentWindow.load_image(
// Set 'ignore' not to call respondWith() in the SW.
REDIRECT_URL + '?ignore&Redirect=' +
encodeURIComponent(IMAGE_URL)),
'When the request was redirected, CSP match algorithm should ' +
'ignore the path component of the URL.');
})
.then(function() {
return assert_resolves(
frame.contentWindow.load_image(
// This request will be fetched via SW and redirected by
// redirect.php.
REDIRECT_URL + '?Redirect=' + encodeURIComponent(IMAGE_URL)),
'When the request was redirected via SW, CSP match algorithm ' +
'should ignore the path component of the URL.');
})
.then(function() {
return assert_resolves(
frame.contentWindow.load_image(
// The request for IMAGE_URL will be fetched in SW.
REDIRECT_URL + '?url=' + encodeURIComponent(IMAGE_URL)),
'When the request was fetched via SW, CSP match algorithm ' +
'should ignore the path component of the URL.');
})
.then(function() {
return assert_resolves(
frame.contentWindow.fetch(IMAGE_URL + "&fetch1", { mode: 'no-cors'}),
'Allowed scope fetch resource should be loaded.');
})
.then(function() {
return assert_resolves(
frame.contentWindow.fetch(
// The request for IMAGE_URL will be fetched in SW.
'./sample?url=' + encodeURIComponent(IMAGE_URL + '&fetch2'), { mode: 'no-cors'}),
'Allowed scope fetch resource which was fetched via SW should be loaded.');
})
.then(function() {
return assert_rejects(
frame.contentWindow.fetch(REMOTE_IMAGE_URL + "&fetch3", { mode: 'no-cors'}),
'Disallowed scope fetch resource should not be loaded.');
})
.then(function() {
return assert_rejects(
frame.contentWindow.fetch(
// The request for REMOTE_IMAGE_URL will be fetched in SW.
'./sample?url=' + encodeURIComponent(REMOTE_IMAGE_URL + '&fetch4'), { mode: 'no-cors'}),
'Disallowed scope fetch resource which was fetched via SW should not be loaded.');
})
.then(function() {
frame.remove();
});
}, 'Verify CSP control of fetch() in a Service Worker');
</script>
|