forked from WebKit/WebKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
https://bugs.webkit.org/show_bug.cgi?id=272884 Reviewed by NOBODY (OOPS!). Imported ES modules can't currently have integrity checks, which means they can't be used in sites where integrity checks are a necessity, for security and privacy reasons. This implements such support, by adding an "integrity" section to import maps. See whatwg/html#10269 * LayoutTests/TestExpectations: Ignored console logs to avoid flakiness * LayoutTests/imported/w3c/web-platform-tests/import-maps/WEB_FEATURES.yml: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/resources/test-helper.js: (createTestIframe): Updated through import. * LayoutTests/imported/w3c/web-platform-tests/import-maps/dynamic-integrity-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/dynamic-integrity.html: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/no-referencing-script-integrity-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/no-referencing-script-integrity-valid-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/no-referencing-script-integrity-valid.html: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/no-referencing-script-integrity.html: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/nonimport-integrity-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/nonimport-integrity.html: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/static-integrity-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/static-integrity.html: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/w3c-import.log: Imports. * LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-resources.https-expected.txt: Updated. * LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html: Updated to cover Request.integrity. * LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html: Updated to cover Request.integrity. * LayoutTests/platform/glib/imported/w3c/web-platform-tests/service-workers/service-worker/fetch-request-resources.https-expected.txt: Updated. * Source/JavaScriptCore/runtime/ImportMap.cpp: (JSC::ImportMap::resolveImportMatch): Typos and spec link. (JSC::parseURLLikeModuleSpecifier): Typos and spec link. (JSC::ImportMap::resolve const): Typos and spec link. (JSC::normalizeSpecifierKey): Typos and spec link. (JSC::sortAndNormalizeSpecifierMap): Typos and spec link. (JSC::ImportMap::registerImportMap): Add parsing for the integrity section. (JSC::ImportMap::getIntegrity const): Getter for integrity based on URL. * Source/JavaScriptCore/runtime/ImportMap.h: * Source/WebCore/bindings/js/ScriptModuleLoader.cpp: (WebCore::ScriptModuleLoader::importModule): Add integrity to outgoing requests. (WebCore::ScriptModuleLoader::notifyFinished): Enforce integrity from the importmap on responses, even if integrity wasn't present in the request. Needed for static imports triggered by JSCore. * Source/WebCore/dom/ScriptElement.cpp: (WebCore::ScriptElement::requestModuleScript): Add integrity to outgoing requests for top-level modules, if they don't already have an integrity attribute.
- Loading branch information
Showing
22 changed files
with
682 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
LayoutTests/imported/w3c/web-platform-tests/import-maps/WEB_FEATURES.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
features: | ||
- name: import-maps | ||
files: "**" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
LayoutTests/imported/w3c/web-platform-tests/import-maps/dynamic-integrity-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
PASS script was not loaded, as its resolved URL failed its integrity check | ||
PASS script was loaded, as its resolved URL had no integrity check, despite its specifier having one | ||
PASS script was loaded, as its integrity check passed | ||
PASS Script with no import definition was not loaded, as it failed its integrity check | ||
PASS Bare specifier script was not loaded, as it failed its integrity check | ||
PASS Bare specifier used for integrity loaded, as its definition should have used the URL | ||
PASS script was loaded, as its integrity check passed, despite having an extra invalid hash | ||
PASS script was loaded, as its integrity check passed, despite having an invalid suffix | ||
PASS script was loaded, as its integrity check passed given multiple hashes. This also makes sure that the larger hash is picked | ||
PASS script was loaded, as its integrity check was ignored, as it was defined using a URL that looks like a bare specifier | ||
PASS Script imported inside an event handler was loaded as its valid integrity check passed | ||
PASS Script imported inside an event handler was not loaded as its integrity check failed | ||
|
124 changes: 124 additions & 0 deletions
124
LayoutTests/imported/w3c/web-platform-tests/import-maps/dynamic-integrity.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"./resources/log.js?pipe=sub&name=ResolvesToBadHash": "./resources/log.js?pipe=sub&name=BadHash", | ||
"./resources/log.js?pipe=sub&name=ResolvesToNoHash": "./resources/log.js?pipe=sub&name=NoHash", | ||
"./resources/log.js?pipe=sub&name=GoodHash": "./resources/log.js?pipe=sub&name=GoodHash", | ||
"bare": "./resources/log.js?pipe=sub&name=BareURL", | ||
"bare2": "./resources/log.js?pipe=sub&name=F" | ||
}, | ||
"integrity": { | ||
"./resources/log.js?pipe=sub&name=BadHash": "sha384-foobar", | ||
"./resources/log.js?pipe=sub&name=ResolvesToNoHash": "sha384-foobar", | ||
"./resources/log.js?pipe=sub&name=GoodHash": "sha384-SwfgBqInhSlLziU454cYhGgwPpae+d3VHZcY+vjZIO/gxRGt2u3Jsfyvure/Ww0u", | ||
"./resources/log.js?pipe=sub&name=InvalidExtra": "sha384-WsKk8nzJFPhk/4pWR4LYoPhEu3xaAc6PdIm4vmqoZVWqEgMYmZgOg9XJKxgD1+8v foobar-rOJN8igD0+jW6lwNN3+InhXTgQztVHlq/HJ0riswXp8kMoiIDx5JpmCwuVem6Ll9q2LFNSu1xq23bsBMMQk1rg==", | ||
"./resources/log.js?pipe=sub&name=Suffix": "sha384-lbOWldbmji7sCHI/L8iVJ+elmFIMp41p+aYOLxqQfZMqtoFeHFVe/ASRA0IyZ1/9?foobar", | ||
"./resources/log.js?pipe=sub&name=Multiple": "sha384-foobar sha512-rOJN8igD0+jW6lwNN3+InhXTgQztVHlq/HJ0riswXp8kMoiIDx5JpmCwuVem6Ll9q2LFNSu1xq23bsBMMQk1rg==", | ||
"./resources/log.js?pipe=sub&name=BadHashWithNoImport": "sha384-foobar", | ||
"./resources/log.js?pipe=sub&name=BareURL": "sha384-foobar", | ||
"./resources/log.js?pipe=sub&name=EventHandlerPass": "sha384-d4yrBK8a55vlyYz2QEnlaU64PPpdKBkblD2KmfozI61mC1ij6RrZJaGCTsVxPuJ2", | ||
"./resources/log.js?pipe=sub&name=EventHandlerFail": "sha384-foobar", | ||
"bare2": "sha384-foobar", | ||
"resources/log.js?pipe=sub&name=Bare": "sha384-foobar" | ||
} | ||
} | ||
</script> | ||
<script> | ||
let log; | ||
const test_not_loaded = (url, description) => { | ||
promise_test(async t => { | ||
log = []; | ||
await promise_rejects_js(t, TypeError, import(url)); | ||
assert_array_equals(log, []); | ||
}, description); | ||
}; | ||
|
||
const test_loaded = (url, log_expectation, description) => { | ||
promise_test(async t => { | ||
log = []; | ||
await import(url); | ||
assert_array_equals(log, log_expectation); | ||
}, description); | ||
}; | ||
|
||
test_not_loaded( | ||
"./resources/log.js?pipe=sub&name=ResolvesToBadHash", | ||
"script was not loaded, as its resolved URL failed its integrity check" | ||
); | ||
test_loaded( | ||
"./resources/log.js?pipe=sub&name=ResolvesToNoHash", | ||
["log:NoHash"], | ||
"script was loaded, as its resolved URL had no integrity check, despite its specifier having one" | ||
); | ||
test_loaded( | ||
"./resources/log.js?pipe=sub&name=GoodHash", | ||
["log:GoodHash"], | ||
"script was loaded, as its integrity check passed" | ||
); | ||
test_not_loaded( | ||
"./resources/log.js?pipe=sub&name=BadHashWithNoImport", | ||
"Script with no import definition was not loaded, as it failed its integrity check" | ||
); | ||
test_not_loaded( | ||
"bare", | ||
"Bare specifier script was not loaded, as it failed its integrity check" | ||
); | ||
test_loaded( | ||
"bare2", | ||
["log:F"], | ||
"Bare specifier used for integrity loaded, as its definition should have used the URL" | ||
); | ||
test_loaded( | ||
"./resources/log.js?pipe=sub&name=InvalidExtra", | ||
["log:InvalidExtra"], | ||
"script was loaded, as its integrity check passed, despite having an extra invalid hash" | ||
); | ||
test_loaded( | ||
"./resources/log.js?pipe=sub&name=Suffix", | ||
["log:Suffix"], | ||
"script was loaded, as its integrity check passed, despite having an invalid suffix" | ||
); | ||
test_loaded( | ||
"./resources/log.js?pipe=sub&name=Multiple", | ||
["log:Multiple"], | ||
"script was loaded, as its integrity check passed given multiple hashes. This also makes sure that the larger hash is picked" | ||
); | ||
test_loaded( | ||
"./resources/log.js?pipe=sub&name=Bare", | ||
["log:Bare"], | ||
"script was loaded, as its integrity check was ignored, as it was defined using a URL that looks like a bare specifier" | ||
); | ||
|
||
promise_test(async () => { | ||
log = []; | ||
const img = new Image(); | ||
const promise = new Promise((resolve, reject) => { | ||
img.onload = () => { | ||
import('./resources/log.js?pipe=sub&name=EventHandlerPass').then(resolve).catch(reject); | ||
}; | ||
img.src = "/images/green.png?1"; | ||
}); | ||
|
||
await promise; | ||
assert_equals(log.length, 1); | ||
assert_equals(log[0], "log:EventHandlerPass"); | ||
}, "Script imported inside an event handler was loaded as its valid integrity check passed"); | ||
|
||
promise_test(async t => { | ||
log = []; | ||
const img = new Image(); | ||
const promise = new Promise((resolve, reject) => { | ||
img.onload = () => { | ||
import('./resources/log.js?pipe=sub&name=EventHandlerFail').then(resolve).catch(reject); | ||
}; | ||
img.src = "/images/green.png?2"; | ||
}); | ||
|
||
await promise_rejects_js(t, TypeError, promise); | ||
}, "Script imported inside an event handler was not loaded as its integrity check failed"); | ||
</script> | ||
|
4 changes: 4 additions & 0 deletions
4
.../imported/w3c/web-platform-tests/import-maps/no-referencing-script-integrity-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
|
||
PASS Script was not loaded as its integrity check failed | ||
|
4 changes: 4 additions & 0 deletions
4
...ted/w3c/web-platform-tests/import-maps/no-referencing-script-integrity-valid-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
|
||
PASS Script was loaded as its valid integrity check passed | ||
|
42 changes: 42 additions & 0 deletions
42
...ts/imported/w3c/web-platform-tests/import-maps/no-referencing-script-integrity-valid.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script> | ||
let log = []; | ||
</script> | ||
<script type="importmap"> | ||
{ | ||
"integrity": { | ||
"./resources/log.js?pipe=sub&name=NoReferencingScriptValidCheck": "sha384-5eRmXQSBE6H5ENdymdZxcyiIfJL1dxtH8p+hOelZY7Jzk+gt0gYyemrGY0cEaThF" | ||
} | ||
} | ||
</script> | ||
<script> | ||
let promiseResolve; | ||
let promiseReject; | ||
let promise = new Promise((resolve, reject) => { | ||
promiseResolve = resolve; | ||
promiseReject = reject; | ||
}); | ||
</script> | ||
</head> | ||
<body> | ||
<!-- This is testing the part of | ||
https://html.spec.whatwg.org/multipage/webappapis.html#hostloadimportedmodule | ||
where step 6's condition is false and referencingScript remains null. | ||
Therefore, the onload event must be defined as an HTML attribute, outside of any script tag. | ||
--> | ||
<img src="/images/green.png?2" | ||
onload="import('./resources/log.js?pipe=sub&name=NoReferencingScriptValidCheck').then(promiseResolve).catch(promiseReject)"> | ||
<script> | ||
promise_test(async () => { | ||
await promise; | ||
assert_equals(log.length, 1); | ||
assert_equals(log[0], "log:NoReferencingScriptValidCheck"); | ||
}, "Script was loaded as its valid integrity check passed"); | ||
</script> | ||
</body> | ||
</html> | ||
|
39 changes: 39 additions & 0 deletions
39
LayoutTests/imported/w3c/web-platform-tests/import-maps/no-referencing-script-integrity.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script> | ||
let log = []; | ||
</script> | ||
<script type="importmap"> | ||
{ | ||
"integrity": { | ||
"./resources/log.js?pipe=sub&name=NoReferencingScriptInvalidCheck": "sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7" | ||
} | ||
} | ||
</script> | ||
<script> | ||
let promiseResolve; | ||
let promiseReject; | ||
let promise = new Promise((resolve, reject) => { | ||
promiseResolve = resolve; | ||
promiseReject = reject; | ||
}); | ||
</script> | ||
</head> | ||
<body> | ||
<!-- This is testing the part of | ||
https://html.spec.whatwg.org/multipage/webappapis.html#hostloadimportedmodule | ||
where step 6's condition is false and referencingScript remains null. | ||
Therefore, the onload event must be defined as an HTML attribute, outside of any script tag. | ||
--> | ||
<img src="/images/green.png" | ||
onload="import('./resources/log.js?pipe=sub&name=NoReferencingScriptInvalidCheck').then(promiseResolve).catch(promiseReject)"> | ||
<script type="module"> | ||
promise_test(async t => { | ||
await promise_rejects_js(t, TypeError, promise); | ||
}, "Script was not loaded as its integrity check failed"); | ||
</script> | ||
</body> | ||
</html> |
12 changes: 12 additions & 0 deletions
12
LayoutTests/imported/w3c/web-platform-tests/import-maps/nonimport-integrity-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
PASS Script was not loaded as its integrity check was not ignored | ||
PASS Script was loaded as its correct integrity attribute was not ignored | ||
PASS Script was loaded as its empty integrity attribute was not ignored | ||
PASS Script was not loaded as its bad integrity attribute was not overridden | ||
FAIL Modulepreload was not loaded as its integrity check was not ignored assert_unreached: Should have rejected: undefined Reached unreachable code | ||
PASS Modulepreload was loaded as its correct integrity attribute was not ignored | ||
PASS Modulepreload was loaded as its empty integrity attribute was not ignored | ||
FAIL Modulepreload was not loaded as its bad integrity attribute was not ignored promise_test: Unhandled rejection with value: object "Error: It shouldn't have loaded" | ||
PASS Classic script was loaded as its integrity check was ignored | ||
PASS Image was loaded as its integrity check was ignored | ||
|
Oops, something went wrong.