Title: [258863] trunk
Revision
258863
Author
[email protected]
Date
2020-03-23 11:47:48 -0700 (Mon, 23 Mar 2020)

Log Message

Add checks for app-bound navigations when evaluating user style sheets
https://bugs.webkit.org/show_bug.cgi?id=209368
<rdar://problem/60204230>

Reviewed by Brent Fulgham.

Source/WebCore:

* page/Page.cpp:
(WebCore::Page::injectUserStyleSheet):
If the style sheet is for a specific WebView, it will have a pageID
and we can check for app-bound navigation in the page object.

* style/StyleScopeRuleSets.cpp:
(WebCore::Style::ScopeRuleSets::initializeUserStyle):
If the user style sheet is being applied to all WebViews, we can check for
for a page's existence and navigation state here before the style sheet is
updated.

Tools:

Tested cases based on those in UserContentController.mm.

* TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
(-[InAppBrowserSchemeHandler webView:startURLSchemeTask:]):
(expectScriptEvaluatesToColor):
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (258862 => 258863)


--- trunk/Source/WebCore/ChangeLog	2020-03-23 18:40:03 UTC (rev 258862)
+++ trunk/Source/WebCore/ChangeLog	2020-03-23 18:47:48 UTC (rev 258863)
@@ -1,3 +1,22 @@
+2020-03-23  Kate Cheney  <[email protected]>
+
+        Add checks for app-bound navigations when evaluating user style sheets
+        https://bugs.webkit.org/show_bug.cgi?id=209368
+        <rdar://problem/60204230>
+
+        Reviewed by Brent Fulgham.
+
+        * page/Page.cpp:
+        (WebCore::Page::injectUserStyleSheet):
+        If the style sheet is for a specific WebView, it will have a pageID
+        and we can check for app-bound navigation in the page object.
+
+        * style/StyleScopeRuleSets.cpp:
+        (WebCore::Style::ScopeRuleSets::initializeUserStyle):
+        If the user style sheet is being applied to all WebViews, we can check for 
+        for a page's existence and navigation state here before the style sheet is
+        updated.
+
 2020-03-23  Antoine Quint  <[email protected]>
 
         DocumentTimeline / CSSTransition objects are leaking on CNN.com

Modified: trunk/Source/WebCore/page/Page.cpp (258862 => 258863)


--- trunk/Source/WebCore/page/Page.cpp	2020-03-23 18:40:03 UTC (rev 258862)
+++ trunk/Source/WebCore/page/Page.cpp	2020-03-23 18:47:48 UTC (rev 258863)
@@ -3075,6 +3075,12 @@
 
 void Page::injectUserStyleSheet(UserStyleSheet& userStyleSheet)
 {
+    if (m_mainFrame->loader().client().hasNavigatedAwayFromAppBoundDomain()) {
+        if (auto* document = m_mainFrame->document())
+            document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user style sheet for non-app bound domain."_s);
+        return;
+    }
+
     // We need to wait until we're no longer displaying the initial empty document before we can inject the stylesheets.
     if (m_mainFrame->loader().stateMachine().isDisplayingInitialEmptyDocument()) {
         m_userStyleSheetsPendingInjection.append(userStyleSheet);

Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.cpp (258862 => 258863)


--- trunk/Source/WebCore/style/StyleScopeRuleSets.cpp	2020-03-23 18:40:03 UTC (rev 258862)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.cpp	2020-03-23 18:47:48 UTC (rev 258863)
@@ -31,7 +31,11 @@
 
 #include "CSSStyleSheet.h"
 #include "ExtensionStyleSheets.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
 #include "MediaQueryEvaluator.h"
+#include "Page.h"
 #include "StyleResolver.h"
 #include "StyleSheetContents.h"
 
@@ -87,7 +91,11 @@
     auto tempUserStyle = RuleSet::create();
     if (CSSStyleSheet* pageUserSheet = extensionStyleSheets.pageUserSheet())
         tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), nullptr, mediaQueryEvaluator, m_styleResolver);
-    collectRulesFromUserStyleSheets(extensionStyleSheets.injectedUserStyleSheets(), tempUserStyle.get(), mediaQueryEvaluator);
+    auto* page = m_styleResolver.document().page();
+    if (page && page->mainFrame().loader().client().hasNavigatedAwayFromAppBoundDomain())
+        m_styleResolver.document().addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user style sheet for non-app bound domain."_s);
+    else
+        collectRulesFromUserStyleSheets(extensionStyleSheets.injectedUserStyleSheets(), tempUserStyle.get(), mediaQueryEvaluator);
     collectRulesFromUserStyleSheets(extensionStyleSheets.documentUserStyleSheets(), tempUserStyle.get(), mediaQueryEvaluator);
     if (tempUserStyle->ruleCount() > 0 || tempUserStyle->pageRules().size() > 0)
         m_userStyle = WTFMove(tempUserStyle);

Modified: trunk/Tools/ChangeLog (258862 => 258863)


--- trunk/Tools/ChangeLog	2020-03-23 18:40:03 UTC (rev 258862)
+++ trunk/Tools/ChangeLog	2020-03-23 18:47:48 UTC (rev 258863)
@@ -1,3 +1,19 @@
+2020-03-23  Kate Cheney  <[email protected]>
+
+        Add checks for app-bound navigations when evaluating user style sheets
+        https://bugs.webkit.org/show_bug.cgi?id=209368
+        <rdar://problem/60204230>
+
+        Reviewed by Brent Fulgham.
+
+        Tested cases based on those in UserContentController.mm.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+        (-[InAppBrowserSchemeHandler webView:startURLSchemeTask:]):
+        (expectScriptEvaluatesToColor):
+        (TEST):
+
+
 2020-03-23  Alex Christensen  <[email protected]>
 
         Add SPI to move localStorage to a different domain

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (258862 => 258863)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2020-03-23 18:40:03 UTC (rev 258862)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2020-03-23 18:47:48 UTC (rev 258863)
@@ -34,6 +34,8 @@
 #import <WebKit/WKPreferencesPrivate.h>
 #import <WebKit/WKUserContentControllerPrivate.h>
 #import <WebKit/WKWebsiteDataStorePrivate.h>
+#import <WebKit/_WKUserContentWorld.h>
+#import <WebKit/_WKUserStyleSheet.h>
 #import <wtf/RunLoop.h>
 #import <wtf/text/WTFString.h>
 
@@ -68,6 +70,10 @@
         response = @"<script>window.webkit.messageHandlers.testInAppBrowserPrivacy.postMessage(\"done\");</script>";
     else if ([task.request.URL.path isEqualToString:@"/in-app-browser-privacy-test-user-agent-script"])
         response = @"<script> window.wkUserScriptInjected = true; </script>";
+    else if ([task.request.URL.path isEqualToString:@"/in-app-browser-privacy-test-user-style-sheets"])
+        response = @"<body style='background-color: red;'></body>";
+    else if ([task.request.URL.path isEqualToString:@"/in-app-browser-privacy-test-user-style-sheets-iframe"])
+        response = @"<body style='background-color: red;'><iframe src=''></iframe></body>";
 
     [task didReceiveResponse:[[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:response.length textEncodingName:nil] autorelease]];
     [task didReceiveData:[response dataUsingEncoding:NSUTF8StringEncoding]];
@@ -411,5 +417,92 @@
     TestWebKitAPI::Util::run(&isDone);
 }
 
+static NSString *styleSheetSource = @"body { background-color: green !important; }";
+static NSString *backgroundColorScript = @"window.getComputedStyle(document.body, null).getPropertyValue('background-color')";
+static NSString *frameBackgroundColorScript = @"window.getComputedStyle(document.getElementsByTagName('iframe')[0].contentDocument.body, null).getPropertyValue('background-color')";
+static const char* redInRGB = "rgb(255, 0, 0)";
+
+static void expectScriptEvaluatesToColor(WKWebView *webView, NSString *script, const char* color)
+{
+    static bool didCheckBackgroundColor;
+
+    [webView evaluateJavaScript:script completionHandler:^(id value, NSError * error) {
+        EXPECT_TRUE([value isKindOfClass:[NSString class]]);
+        EXPECT_WK_STREQ(color, value);
+        didCheckBackgroundColor = true;
+    }];
+
+    TestWebKitAPI::Util::run(&didCheckBackgroundColor);
+    didCheckBackgroundColor = false;
+}
+
+TEST(InAppBrowserPrivacy, NonAppBoundUserStyleSheetForSpecificWebViewFails)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+
+    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+    [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+    [webView loadRequest:request];
+    [webView _test_waitForDidFinishNavigation];
+
+    RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
+    RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forWKWebView:webView.get() forMainFrameOnly:YES userContentWorld:world.get()]);
+    [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
+
+    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
+}
+
+TEST(InAppBrowserPrivacy, NonAppBoundUserStyleSheetForAllWebViewsFails)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+
+    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+    [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+    [webView loadRequest:request];
+    [webView _test_waitForDidFinishNavigation];
+
+    RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:YES]);
+    [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
+
+    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
+}
+
+TEST(InAppBrowserPrivacy, NonAppBoundUserStyleSheetAffectingAllFramesFails)
+{
+    initializeInAppBrowserPrivacyTestSettings();
+
+    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+    auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+    [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets-iframe"]];
+    [webView loadRequest:request];
+    [webView _test_waitForDidFinishNavigation];
+
+    RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
+    [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
+
+    // The main frame should be affected.
+    expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
+
+    // The subframe should also be affected.
+    expectScriptEvaluatesToColor(webView.get(), frameBackgroundColorScript, redInRGB);
+}
+
 #endif // USE(APPLE_INTERNAL_SDK)
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to