Skip to content

Commit

Permalink
Subresource Integrity support for ES modules, using importmaps
Browse files Browse the repository at this point in the history
SRI support for ES modules enables using them in documents that require
SRI for certain scripts for security reasons, as well as with the move
overarching require-sri-for CSP directive.

This CL implements whatwg/html#10269
based on https://github.com/guybedford/import-maps-extensions#integrity

I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/O2UR3kb-HcI/m/7Jh7_GYsAAAJ?utm_medium=email&utm_source=footer

Change-Id: Ida563334048d013ffc658f9783f9401930dd4689
Bug: 334251999
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5441822
Reviewed-by: Domenic Denicola <domenic@chromium.org>
Commit-Queue: Yoav Weiss (@Shopify) <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1297376}
  • Loading branch information
Yoav Weiss authored and Chromium LUCI CQ committed May 7, 2024
1 parent 06fbb90 commit 18f9d2c
Show file tree
Hide file tree
Showing 32 changed files with 863 additions and 123 deletions.
Expand Up @@ -423,33 +423,32 @@ void ModuleTreeLinker::FetchDescendants(const ModuleScript* module_script) {
return;
}

// <spec step="6">Let options be the descendant script fetch options for
// module script's fetch options.</spec>
//
// <spec
// href="https://html.spec.whatwg.org/C/#descendant-script-fetch-options"> For
// any given script fetch options options, the descendant script fetch options
// are a new script fetch options whose items all have the same values, except
// for the integrity metadata, which is instead the empty string.</spec>
//
// <spec
// href="https://wicg.github.io/priority-hints/#script">
// descendant scripts get "auto" fetchpriority (only the main script resource
// is affected by Priority Hints).
ScriptFetchOptions options(module_script->FetchOptions().Nonce(),
IntegrityMetadataSet(), String(),
module_script->FetchOptions().ParserState(),
module_script->FetchOptions().CredentialsMode(),
module_script->FetchOptions().GetReferrerPolicy(),
mojom::blink::FetchPriorityHint::kAuto,
RenderBlockingBehavior::kNonBlocking);

// <spec step="8">For each moduleRequest in moduleRequests, ...</spec>
//
// <spec step="8">... These invocations of the internal module script graph
// fetching procedure should be performed in parallel to each other.
// ...</spec>
for (const auto& module_request : module_requests) {
// <spec
// href="https://html.spec.whatwg.org/C/#descendant-script-fetch-options">
// For any given script fetch options options, the descendant script fetch
// options are a new script fetch options whose items all have the same
// values, except for the integrity metadata, which is instead the empty
// string.</spec>
//
// <spec
// href="https://wicg.github.io/priority-hints/#script">
// descendant scripts get "auto" fetchpriority (only the main script
// resource is affected by Priority Hints).
ScriptFetchOptions options(
module_script->FetchOptions().Nonce(),
modulator_->GetIntegrityMetadata(module_request.url),
modulator_->GetIntegrityMetadataString(module_request.url),
module_script->FetchOptions().ParserState(),
module_script->FetchOptions().CredentialsMode(),
module_script->FetchOptions().GetReferrerPolicy(),
mojom::blink::FetchPriorityHint::kAuto,
RenderBlockingBehavior::kNonBlocking);
// <spec step="8">... perform the internal module script graph fetching
// procedure given moduleRequest, fetch client settings object, destination,
// options, module script's settings object, visited set, and module
Expand Down
19 changes: 13 additions & 6 deletions third_party/blink/renderer/core/loader/preload_helper.cc
Expand Up @@ -626,37 +626,44 @@ void PreloadHelper::ModulePreloadIfNeeded(
// is specified, or the empty string otherwise." [spec text]
// |nonce| parameter is the value of the nonce attribute.

// Step 8. "Let integrity metadata be the value of the integrity attribute, if
// Step 9. "Let integrity metadata be the value of the integrity attribute, if
// it is specified, or the empty string otherwise." [spec text]
IntegrityMetadataSet integrity_metadata;
if (!params.integrity.empty()) {
String integrity_value = params.integrity;
if (!integrity_value.empty()) {
SubresourceIntegrity::IntegrityFeatures integrity_features =
SubresourceIntegrityHelper::GetFeatures(document.GetExecutionContext());
SubresourceIntegrity::ReportInfo report_info;
SubresourceIntegrity::ParseIntegrityAttribute(
params.integrity, integrity_features, integrity_metadata, &report_info);
SubresourceIntegrityHelper::DoReport(*document.GetExecutionContext(),
report_info);
} else if (integrity_value.IsNull()) {
// Step 10. "If el does not have an integrity attribute, then set integrity
// metadata to the result of resolving a module integrity metadata with url
// and settings object." [spec text]
integrity_value = modulator->GetIntegrityMetadataString(params.href);
integrity_metadata = modulator->GetIntegrityMetadata(params.href);
}

// Step 9. "Let referrer policy be the current state of the element's
// Step 11. "Let referrer policy be the current state of the element's
// referrerpolicy attribute." [spec text]
// |referrer_policy| parameter is the value of the referrerpolicy attribute.

// Step 10. "Let options be a script fetch options whose cryptographic nonce
// Step 12. "Let options be a script fetch options whose cryptographic nonce
// is cryptographic nonce, integrity metadata is integrity metadata, parser
// metadata is "not-parser-inserted", credentials mode is credentials mode,
// and referrer policy is referrer policy." [spec text]
ModuleScriptFetchRequest request(
params.href, ModuleType::kJavaScript, context_type, destination,
ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity,
ScriptFetchOptions(params.nonce, integrity_metadata, integrity_value,
kNotParserInserted, credentials_mode,
params.referrer_policy,
mojom::blink::FetchPriorityHint::kAuto,
RenderBlockingBehavior::kNonBlocking),
Referrer::NoReferrer(), TextPosition::MinimumPosition());

// Step 11. "Fetch a modulepreload module script graph given url, destination,
// Step 13. "Fetch a modulepreload module script graph given url, destination,
// settings object, and options. Wait until the algorithm asynchronously
// completes with result." [spec text]
//
Expand Down
Expand Up @@ -281,10 +281,12 @@ void DynamicModuleResolver::ResolveDynamically(
// <spec href="https://wicg.github.io/priority-hints/#script">
// dynamic imports get kAuto. Only the main script resource is impacted by
// Priority Hints.
//
ScriptFetchOptions options(
referrer_info.Nonce(), IntegrityMetadataSet(), String(),
referrer_info.ParserState(), referrer_info.CredentialsMode(),
referrer_info.GetReferrerPolicy(), mojom::blink::FetchPriorityHint::kAuto,
referrer_info.Nonce(), modulator_->GetIntegrityMetadata(url),
modulator_->GetIntegrityMetadataString(url), referrer_info.ParserState(),
referrer_info.CredentialsMode(), referrer_info.GetReferrerPolicy(),
mojom::blink::FetchPriorityHint::kAuto,
RenderBlockingBehavior::kNonBlocking);

// <spec label="fetch-an-import()-module-script-graph" step="3">Fetch a single
Expand Down

0 comments on commit 18f9d2c

Please sign in to comment.