Skip to content
Permalink
Browse files
Add support for Link nonces
https://bugs.webkit.org/show_bug.cgi?id=240817

This reads the nonce from link elements and Link headers.

This was implemented by Chromium in 2017 to be consistent with the HTMLPreloader:
https://chromium-review.googlesource.com/c/chromium/src/+/676769/

Reviewed by Kate Cheney.

* LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/preload/link-header-preload-nonce.html:

These test changes were already upstream: web-platform-tests/wpt@306dc50

* Source/WebCore/html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::process):
* Source/WebCore/loader/LinkHeader.cpp:
(WebCore::paramterNameFromString):
(WebCore::LinkHeader::setValue):
* Source/WebCore/loader/LinkHeader.h:
(WebCore::LinkHeader::nonce const):
* Source/WebCore/loader/LinkLoader.cpp:
(WebCore::LinkLoader::loadLinksFromHeader):
(WebCore::LinkLoader::preloadIfNeeded):
(WebCore::LinkLoader::prefetchIfNeeded):
* Source/WebCore/loader/LinkLoader.h:

Canonical link: https://commits.webkit.org/250972@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294819 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
TingPing committed May 25, 2022
1 parent 5921362 commit c59d9a35751f739d526ecc48ea1c19a3d6cca25e
Showing 7 changed files with 15 additions and 6 deletions.
@@ -1,7 +1,4 @@
CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/dummy.js?from-header&without-nonce because it does not appear in the script-src directive of the Content Security Policy.
CONSOLE MESSAGE: Refused to load http://localhost:8800/preload/resources/dummy.js?from-header&with-nonce because it does not appear in the script-src directive of the Content Security Policy.
CONSOLE MESSAGE: Error: assert_equals: resources/dummy.js?from-header&with-nonce expected 1 but got 0

Harness Error (FAIL), message = Error: assert_equals: resources/dummy.js?from-header&with-nonce expected 1 but got 0

PASS Makes sure that Link headers preload resources with CSP nonce

@@ -5,7 +5,7 @@
<script nonce="abc" src="/preload/resources/preload_helper.js"></script>
<body>
<script nonce="abc">
setup({explicit_done: true});
setup({single_test: true});

var iterations = 0;

@@ -263,6 +263,7 @@ void HTMLLinkElement::process()
attributeWithoutSynchronization(crossoriginAttr),
attributeWithoutSynchronization(imagesrcsetAttr),
attributeWithoutSynchronization(imagesizesAttr),
nonce(),
referrerPolicy(),
};

@@ -157,6 +157,8 @@ static LinkHeader::LinkParameterName paramterNameFromString(StringView name)
return LinkHeader::LinkParameterImageSrcSet;
if (equalLettersIgnoringASCIICase(name, "imagesizes"_s))
return LinkHeader::LinkParameterImageSizes;
if (equalLettersIgnoringASCIICase(name, "nonce"_s))
return LinkHeader::LinkParameterNonce;
return LinkHeader::LinkParameterUnknown;
}

@@ -280,6 +282,9 @@ void LinkHeader::setValue(LinkParameterName name, String&& value)
case LinkParameterImageSizes:
m_imageSizes = WTFMove(value);
break;
case LinkParameterNonce:
m_nonce = WTFMove(value);
break;
case LinkParameterTitle:
case LinkParameterRev:
case LinkParameterHreflang:
@@ -44,6 +44,7 @@ class LinkHeader {
const String& crossOrigin() const { return m_crossOrigin; }
const String& imageSrcSet() const { return m_imageSrcSet; }
const String& imageSizes() const { return m_imageSizes; }
const String& nonce() const { return m_nonce; }
bool valid() const { return m_isValid; }
bool isViewportDependent() const { return !media().isEmpty() || !imageSrcSet().isEmpty() || !imageSizes().isEmpty(); }

@@ -61,6 +62,7 @@ class LinkHeader {
LinkParameterAs,
LinkParameterImageSrcSet,
LinkParameterImageSizes,
LinkParameterNonce,
};

private:
@@ -74,6 +76,7 @@ class LinkHeader {
String m_crossOrigin;
String m_imageSrcSet;
String m_imageSizes;
String m_nonce;
bool m_isValid { true };
};

@@ -112,7 +112,7 @@ void LinkLoader::loadLinksFromHeader(const String& headerValue, const URL& baseU
if (equalIgnoringFragmentIdentifier(url, baseURL))
continue;

LinkLoadParameters params { relAttribute, url, header.as(), header.media(), header.mimeType(), header.crossOrigin(), header.imageSrcSet(), header.imageSizes(), ReferrerPolicy::EmptyString };
LinkLoadParameters params { relAttribute, url, header.as(), header.media(), header.mimeType(), header.crossOrigin(), header.imageSrcSet(), header.imageSizes(), header.nonce(), ReferrerPolicy::EmptyString };
preconnectIfNeeded(params, document);
preloadIfNeeded(params, document, nullptr);
}
@@ -261,6 +261,7 @@ std::unique_ptr<LinkPreloadResourceClient> LinkLoader::preloadIfNeeded(const Lin

auto options = CachedResourceLoader::defaultCachedResourceOptions();
options.referrerPolicy = params.referrerPolicy;
options.nonce = params.nonce;
auto linkRequest = createPotentialAccessControlRequest(url, WTFMove(options), document, params.crossOrigin);
linkRequest.setPriority(DefaultResourceLoadPriority::forResourceType(type.value()));
linkRequest.setInitiator("link"_s);
@@ -302,6 +303,7 @@ void LinkLoader::prefetchIfNeeded(const LinkLoadParameters& params, Document& do
options.serviceWorkersMode = ServiceWorkersMode::None;
options.cachingPolicy = CachingPolicy::DisallowCaching;
options.referrerPolicy = params.referrerPolicy;
options.nonce = params.nonce;
m_cachedLinkResource = document.cachedResourceLoader().requestLinkResource(type, CachedResourceRequest(ResourceRequest { document.completeURL(params.href.string()) }, options, priority)).value_or(nullptr);
if (m_cachedLinkResource)
m_cachedLinkResource->addClient(*this);
@@ -52,6 +52,7 @@ struct LinkLoadParameters {
String crossOrigin;
String imageSrcSet;
String imageSizes;
String nonce;
ReferrerPolicy referrerPolicy { ReferrerPolicy::EmptyString };
};

0 comments on commit c59d9a3

Please sign in to comment.