Diff
Modified: trunk/Source/WebCore/ChangeLog (287413 => 287414)
--- trunk/Source/WebCore/ChangeLog 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Source/WebCore/ChangeLog 2021-12-23 23:09:43 UTC (rev 287414)
@@ -1,3 +1,23 @@
+2021-12-23 Matt Woodrow <[email protected]>
+
+ Check allowed network hosts list when we schedule the load in the network process
+ https://bugs.webkit.org/show_bug.cgi?id=234543
+ <rdar://83501315>
+
+ Reviewed by Alex Christensen.
+
+ The check for WKWebViewConfiguration._allowedNetworkHost previously happened before the check to see if
+ the given ResourceRequest would directly from an archive.
+ This moves to the allowed network host list check to happen when we schedule the network request, and thus
+ allows subresources cached within an archive to load, even if their original URL would be blocked.
+
+ New test LoadWebArchive.DisallowedNetworkHosts added.
+
+ * loader/ResourceLoadNotifier.cpp:
+ (WebCore::ResourceLoadNotifier::dispatchWillSendRequest):
+ * loader/ResourceLoadNotifier.h:
+ (WebCore::ResourceLoadNotifier::isInitialRequestIdentifier):
+
2021-12-23 Brady Eidson <[email protected]>
Add WTF::UUID class which is natively a 128-bit integer
Modified: trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp (287413 => 287414)
--- trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Source/WebCore/loader/ResourceLoadNotifier.cpp 2021-12-23 23:09:43 UTC (rev 287414)
@@ -137,12 +137,6 @@
Ref<Frame> protectedFrame(m_frame);
m_frame.loader().client().dispatchWillSendRequest(loader, identifier, request, redirectResponse);
- if (auto* page = m_frame.page()) {
- auto mainFrameMainResource = m_frame.isMainFrame() && m_initialRequestIdentifier == identifier ? MainFrameMainResource::Yes : MainFrameMainResource::No;
- if (!page->allowsLoadFromURL(request.url(), mainFrameMainResource))
- request = { };
- }
-
// If the URL changed, then we want to put that new URL in the "did tell client" set too.
if (!request.isNull() && oldRequestURL != request.url().string() && m_frame.loader().documentLoader())
m_frame.loader().documentLoader()->didTellClientAboutLoad(request.url().string());
Modified: trunk/Source/WebCore/loader/ResourceLoadNotifier.h (287413 => 287414)
--- trunk/Source/WebCore/loader/ResourceLoadNotifier.h 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Source/WebCore/loader/ResourceLoadNotifier.h 2021-12-23 23:09:43 UTC (rev 287414)
@@ -68,6 +68,11 @@
void sendRemainingDelegateMessages(DocumentLoader*, ResourceLoaderIdentifier, const ResourceRequest&, const ResourceResponse&, const uint8_t* data, int dataLength, int encodedDataLength, const ResourceError&);
+ bool isInitialRequestIdentifier(ResourceLoaderIdentifier identifier)
+ {
+ return m_initialRequestIdentifier == identifier;
+ }
+
private:
Frame& m_frame;
std::optional<ResourceLoaderIdentifier> m_initialRequestIdentifier;
Modified: trunk/Source/WebCore/loader/ResourceLoader.h (287413 => 287414)
--- trunk/Source/WebCore/loader/ResourceLoader.h 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Source/WebCore/loader/ResourceLoader.h 2021-12-23 23:09:43 UTC (rev 287414)
@@ -85,7 +85,7 @@
WEBCORE_EXPORT void start();
WEBCORE_EXPORT void cancel(const ResourceError&);
WEBCORE_EXPORT ResourceError cancelledError();
- ResourceError blockedError();
+ WEBCORE_EXPORT ResourceError blockedError();
ResourceError blockedByContentBlockerError();
ResourceError cannotShowURLError();
Modified: trunk/Source/WebKit/ChangeLog (287413 => 287414)
--- trunk/Source/WebKit/ChangeLog 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Source/WebKit/ChangeLog 2021-12-23 23:09:43 UTC (rev 287414)
@@ -1,3 +1,27 @@
+2021-12-23 Matt Woodrow <[email protected]>
+
+ Check allowed network hosts list when we schedule the load in the network process
+ https://bugs.webkit.org/show_bug.cgi?id=234543
+ <rdar://83501315>
+
+ Reviewed by Alex Christensen.
+
+ The check for WKWebViewConfiguration._allowedNetworkHost previously happened before the check to see if
+ the given ResourceRequest would directly from an archive.
+ This moves to the allowed network host list check to happen when we schedule the network request, and thus
+ allows subresources cached within an archive to load, even if their original URL would be blocked.
+ We also need to check when redirecting to prevent an allowed domain from redirecting to a forbidden domain.
+ This also makes it so that WKWebViewConfiguration._loadsSubresources only prevents
+ subresource loads that would touch the network, so we can't use WKURLSchemeHandler to test it any more.
+ That's fine, since the two users of the SPI only load URLs from the network.
+
+ New test LoadWebArchive.DisallowedNetworkHosts added.
+
+ * WebProcess/Network/WebLoaderStrategy.cpp:
+ (WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess):
+ * WebProcess/Network/WebResourceLoader.cpp:
+ (WebKit::WebResourceLoader::willSendRequest):
+
2021-12-23 Brent Fulgham <[email protected]>
Allow a necessary syscall in the WebContent sandbox
Modified: trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp (287413 => 287414)
--- trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp 2021-12-23 23:09:43 UTC (rev 287414)
@@ -299,6 +299,21 @@
auto identifier = resourceLoader.identifier();
ASSERT(identifier);
+ auto* frame = resourceLoader.frame();
+
+ if (auto* page = frame ? frame->page() : nullptr) {
+ auto mainFrameMainResource = frame->isMainFrame()
+ && resourceLoader.frameLoader()
+ && resourceLoader.frameLoader()->notifier().isInitialRequestIdentifier(identifier)
+ ? MainFrameMainResource::Yes : MainFrameMainResource::No;
+ if (!page->allowsLoadFromURL(request.url(), mainFrameMainResource)) {
+ RunLoop::main().dispatch([resourceLoader = Ref { resourceLoader }] {
+ resourceLoader->didFail(resourceLoader->blockedError());
+ });
+ return;
+ }
+ }
+
ContentSniffingPolicy contentSniffingPolicy = resourceLoader.shouldSniffContent() ? ContentSniffingPolicy::SniffContent : ContentSniffingPolicy::DoNotSniffContent;
ContentEncodingSniffingPolicy contentEncodingSniffingPolicy = resourceLoader.shouldSniffContentEncoding() ? ContentEncodingSniffingPolicy::Sniff : ContentEncodingSniffingPolicy::DoNotSniff;
StoredCredentialsPolicy storedCredentialsPolicy = resourceLoader.shouldUseCredentialStorage() ? StoredCredentialsPolicy::Use : StoredCredentialsPolicy::DoNotUse;
@@ -305,8 +320,6 @@
LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled with the NetworkProcess with priority %d, storedCredentialsPolicy %i", resourceLoader.url().string().latin1().data(), static_cast<int>(resourceLoader.request().priority()), (int)storedCredentialsPolicy);
- auto* frame = resourceLoader.frame();
-
NetworkResourceLoadParameters loadParameters;
loadParameters.identifier = identifier;
loadParameters.webPageProxyID = trackingParameters.webPageProxyID;
Modified: trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp (287413 => 287414)
--- trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp 2021-12-23 23:09:43 UTC (rev 287414)
@@ -106,6 +106,17 @@
WEBRESOURCELOADER_RELEASE_LOG("willSendRequest: exiting early because maybeLoadFallbackForRedirect returned false");
return;
}
+
+ if (auto* frame = m_coreLoader->frame()) {
+ if (auto* page = frame->page()) {
+ auto mainFrameMainResource = frame->isMainFrame()
+ && m_coreLoader->frameLoader()
+ && m_coreLoader->frameLoader()->notifier().isInitialRequestIdentifier(m_coreLoader->identifier())
+ ? MainFrameMainResource::Yes : MainFrameMainResource::No;
+ if (!page->allowsLoadFromURL(proposedRequest.url(), mainFrameMainResource))
+ proposedRequest = { };
+ }
+ }
m_coreLoader->willSendRequest(WTFMove(proposedRequest), redirectResponse, [this, protectedThis = WTFMove(protectedThis)](ResourceRequest&& request) {
if (!m_coreLoader || !m_coreLoader->identifier()) {
Modified: trunk/Tools/ChangeLog (287413 => 287414)
--- trunk/Tools/ChangeLog 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Tools/ChangeLog 2021-12-23 23:09:43 UTC (rev 287414)
@@ -1,3 +1,21 @@
+2021-12-23 Matt Woodrow <[email protected]>
+
+ Check allowed network hosts list when we schedule the load in the network process
+ https://bugs.webkit.org/show_bug.cgi?id=234543
+ <rdar://83501315>
+
+ Reviewed by Alex Christensen.
+
+ The check for WKWebViewConfiguration._allowedNetworkHost previously happened before the check to see if
+ the given ResourceRequest would directly from an archive.
+ This moves to the allowed network host list check to happen when we schedule the network request, and thus
+ allows subresources cached within an archive to load, even if their original URL would be blocked.
+
+ New test LoadWebArchive.DisallowedNetworkHosts added.
+
+ * TestWebKitAPI/Tests/mac/LoadWebArchive.mm:
+ (TestWebKitAPI::TEST):
+
2021-12-23 Brady Eidson <[email protected]>
Add WTF::UUID class which is natively a 128-bit integer
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm (287413 => 287414)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm 2021-12-23 23:09:43 UTC (rev 287414)
@@ -1255,36 +1255,43 @@
EXPECT_EQ(server127001.totalRequests(), 2u);
}
-TEST(URLSchemeHandler, LoadsSubresources)
+static void serverLoop(const TestWebKitAPI::Connection& connection, bool& loadedImage, bool& loadedIFrame)
{
+ using namespace TestWebKitAPI;
+ connection.receiveHTTPRequest([&, connection] (Vector<char>&& request) {
+ auto path = HTTPServer::parsePath(request);
+ auto sendReply = [&, connection] (const HTTPResponse& response) {
+ connection.send(response.serialize(), [&, connection] {
+ serverLoop(connection, loadedImage, loadedIFrame);
+ });
+ };
+ if (path == "/main.html")
+ sendReply({ { { "Content-Type", "text/html" } }, "<img src=''></img><iframe src=''></iframe>" });
+ else if (path == "/imgsrc") {
+ loadedImage = true;
+ sendReply({ "image content" });
+ } else if (path == "/iframesrc") {
+ loadedIFrame = true;
+ sendReply({ "iframe content" });
+ } else
+ ASSERT_NOT_REACHED();
+ });
+}
+
+TEST(WKWebViewConfiguration, LoadsSubresources)
+{
bool loadedImage = false;
bool loadedIFrame = false;
- auto handler = adoptNS([TestURLSchemeHandler new]);
-
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
- [configuration setURLSchemeHandler:handler.get() forURLScheme:@"test"];
- [handler setStartURLSchemeTaskHandler:[&](WKWebView *, id<WKURLSchemeTask> task) {
- NSString *response = nil;
- if ([task.request.URL.path isEqualToString:@"/main.html"])
- response = @"<img src=''></img><iframe src=''></iframe>";
- else if ([task.request.URL.path isEqualToString:@"/imgsrc"]) {
- response = @"image content";
- loadedImage = true;
- } else if ([task.request.URL.path isEqualToString:@"/iframesrc"]) {
- response = @"iframe content";
- loadedIFrame = true;
- } else
- ASSERT_NOT_REACHED();
- [task didReceiveResponse:adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:response.length textEncodingName:nil]).get()];
- [task didReceiveData:[response dataUsingEncoding:NSUTF8StringEncoding]];
- [task didFinish];
- }];
-
+ TestWebKitAPI::HTTPServer server([&] (const TestWebKitAPI::Connection& connection) {
+ serverLoop(connection, loadedIFrame, loadedImage);
+ });
+
{
auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
- [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test://host1/main.html"]]];
+ [webView loadRequest:server.request("/main.html")];
TestWebKitAPI::Util::run(&loadedImage);
TestWebKitAPI::Util::run(&loadedIFrame);
}
@@ -1297,7 +1304,7 @@
auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
auto delegate = adoptNS([TestNavigationDelegate new]);
webView.get().navigationDelegate = delegate.get();
- [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test://host1/main.html"]]];
+ [webView loadRequest:server.request("/main.html")];
[delegate waitForDidFinishNavigation];
TestWebKitAPI::Util::spinRunLoop(100);
EXPECT_FALSE(loadedIFrame);
Modified: trunk/Tools/TestWebKitAPI/Tests/mac/LoadWebArchive.mm (287413 => 287414)
--- trunk/Tools/TestWebKitAPI/Tests/mac/LoadWebArchive.mm 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/LoadWebArchive.mm 2021-12-23 23:09:43 UTC (rev 287414)
@@ -33,6 +33,7 @@
#import <WebKit/WKDragDestinationAction.h>
#import <WebKit/WKNavigationPrivate.h>
#import <WebKit/WKWebView.h>
+#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <wtf/RetainPtr.h>
#import <wtf/text/WTFString.h>
@@ -204,7 +205,7 @@
EXPECT_WK_STREQ(finalURL, "");
}
-TEST(LoadWebArchive, HTTPSUpgrade)
+static NSData* constructArchive()
{
NSString *js = @"alert('loaded http subresource successfully')";
auto response = adoptNS([[NSURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://download/script.js"] MIMEType:@"application/_javascript_" expectedContentLength:js.length textEncodingName:@"utf-8"]);
@@ -226,11 +227,28 @@
@"WebResourceURL": @"http://download/script.js",
}]
};
- NSData *data = "" dataFromPropertyList:archive format:NSPropertyListBinaryFormat_v1_0 errorDescription:nil];
+ return [NSPropertyListSerialization dataFromPropertyList:archive format:NSPropertyListBinaryFormat_v1_0 errorDescription:nil];
+}
+TEST(LoadWebArchive, HTTPSUpgrade)
+{
+ NSData *data = ""
+
auto webView = adoptNS([WKWebView new]);
[webView loadData:data MIMEType:@"application/x-webarchive" characterEncodingName:@"utf-8" baseURL:[NSURL URLWithString:@"http://download/"]];
EXPECT_WK_STREQ([webView _test_waitForAlert], "loaded http subresource successfully");
}
+TEST(LoadWebArchive, DisallowedNetworkHosts)
+{
+ NSData *data = ""
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ configuration.get()._allowedNetworkHosts = [NSSet set];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+ [webView loadData:data MIMEType:@"application/x-webarchive" characterEncodingName:@"utf-8" baseURL:[NSURL URLWithString:@"http://download/"]];
+ EXPECT_WK_STREQ([webView _test_waitForAlert], "loaded http subresource successfully");
+}
+
} // namespace TestWebKitAPI
Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h (287413 => 287414)
--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.h 2021-12-23 23:09:43 UTC (rev 287414)
@@ -117,7 +117,7 @@
HTTPResponse& operator=(HTTPResponse&&) = default;
enum class IncludeContentLength : bool { No, Yes };
- Vector<uint8_t> serialize(IncludeContentLength = IncludeContentLength::Yes);
+ Vector<uint8_t> serialize(IncludeContentLength = IncludeContentLength::Yes) const;
static Vector<uint8_t> bodyFromString(const String&);
unsigned statusCode { 200 };
Modified: trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm (287413 => 287414)
--- trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm 2021-12-23 22:00:33 UTC (rev 287413)
+++ trunk/Tools/TestWebKitAPI/cocoa/HTTPServer.mm 2021-12-23 23:09:43 UTC (rev 287414)
@@ -483,7 +483,7 @@
return vector;
}
-Vector<uint8_t> HTTPResponse::serialize(IncludeContentLength includeContentLength)
+Vector<uint8_t> HTTPResponse::serialize(IncludeContentLength includeContentLength) const
{
StringBuilder responseBuilder;
responseBuilder.append("HTTP/1.1 ", statusCode, ' ', statusText(statusCode), "\r\n");