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>
|