LayoutTests:
authorkmccullo <kmccullo@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Mar 2007 07:04:16 +0000 (07:04 +0000)
committerkmccullo <kmccullo@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Mar 2007 07:04:16 +0000 (07:04 +0000)
        Reviewed by Mark and Dave H.

- rdar://problem/5038491
        An oversite of the security fix that prevented remote from loading local is that it
        prevents user style sheets when the site is remote.  This fixes that.

        * http/tests/security/local-user-CSS-from-remote-expected.txt: Added.
        * http/tests/security/local-user-CSS-from-remote.html: Added.

WebCore:

        Reviewed by Mark and Dave H.

        - rdar://problem/5038491
        An oversite of the security fix that prevented remote from loading local is that it
        prevents user style sheets when the site is remote.  This fixes that.

        * loader/Cache.cpp: Propogate and check user style sheet flag.
        (WebCore::createResource):
        (WebCore::Cache::requestResource):
        * loader/Cache.h: Propogate user style sheet flag.
        * loader/CachedCSSStyleSheet.cpp: Propogate user style sheet flag.
        (WebCore::CachedCSSStyleSheet::CachedCSSStyleSheet):
        * loader/CachedCSSStyleSheet.h: Propogate user style sheet flag.
        * loader/DocLoader.cpp: Propogate user style sheet flag.
        (WebCore::DocLoader::requestResource):
        * loader/SubresourceLoader.cpp: Propogate and check user style sheet flag.
        (WebCore::SubresourceLoader::create):
        * loader/SubresourceLoader.h: Add check for user style sheet flag.
        * loader/loader.cpp: Propogate user style sheet flag.
        (WebCore::Loader::load):
        (WebCore::Loader::servePendingRequests):
        * loader/loader.h: Propogate user style sheet flag.

WebKitTools:

        Reviewed by Mark and Dave H.

        - rdar://problem/4922454
        - This fixes a security issue by making remote referrers not able to access local
        resources, unless they register their schemes to be treated as local. The result is
        that those schemes can access local resources and cannot be accessed by remote
        referrers.
        Because this behavior is new a link-on-or-after check is made to determine if the
        app should use the older, less safe, behavior.

        * DumpRenderTree/DumpRenderTree.m: Add ability to set user style sheet to DRT.
        (+[LayoutTestController isSelectorExcludedFromWebScript:]):
        (+[LayoutTestController webScriptNameForSelector:]):
        (-[LayoutTestController setUserStyleSheetLocation:]):
        (-[LayoutTestController setUserStyleSheetEnabled:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@19977 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/security/local-user-CSS-from-remote-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/local-user-CSS-from-remote.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/loader/Cache.cpp
WebCore/loader/Cache.h
WebCore/loader/CachedCSSStyleSheet.cpp
WebCore/loader/CachedCSSStyleSheet.h
WebCore/loader/DocLoader.cpp
WebCore/loader/SubresourceLoader.cpp
WebCore/loader/SubresourceLoader.h
WebCore/loader/loader.cpp
WebCore/loader/loader.h
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/DumpRenderTree.m

index 8e511fe65017bea0c4f8bf5f16dba6721e2e9f3d..7511ff39793c28d65b88da256c7321126687e782 100644 (file)
@@ -1,3 +1,14 @@
+2007-03-05  Kevin McCullough  <kmccullough@apple.com>
+
+        Reviewed by Mark and Dave H.
+
+       - rdar://problem/5038491
+        An oversite of the security fix that prevented remote from loading local is that it
+        prevents user style sheets when the site is remote.  This fixes that.
+
+        * http/tests/security/local-user-CSS-from-remote-expected.txt: Added.
+        * http/tests/security/local-user-CSS-from-remote.html: Added.
+
 2007-03-06  Nikolas Zimmermann  <zimmermann@kde.org>
 
         Reviewed by Darin.
diff --git a/LayoutTests/http/tests/security/local-user-CSS-from-remote-expected.txt b/LayoutTests/http/tests/security/local-user-CSS-from-remote-expected.txt
new file mode 100644 (file)
index 0000000..371030c
--- /dev/null
@@ -0,0 +1,6 @@
+This test is to see if a remote file can include a local user stylesheet. 
+To run this test manually you must set your user style sheet in your Safari preferences to LayoutTests/http/tests/security/resources/cssStyle.css 
+If the background is yellow then the user stylesheet was loaded.
+
+Test Passed: Local user stylesheet loaded.
+
diff --git a/LayoutTests/http/tests/security/local-user-CSS-from-remote.html b/LayoutTests/http/tests/security/local-user-CSS-from-remote.html
new file mode 100644 (file)
index 0000000..48b0b01
--- /dev/null
@@ -0,0 +1,51 @@
+<html>
+    <head>
+        <title>User Stylesheet Test</title>
+        <script type="text/javascript">
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+
+                // This won't work outside of DRT!
+                if (window.location.hash == '') {
+                    layoutTestController.waitUntilDone();
+                    layoutTestController.setUserStyleSheetLocation("file:///tmp/LayoutTests/http/tests/security/resources/cssStyle.css");
+                    layoutTestController.setUserStyleSheetEnabled(true);
+                    location += '?#done';
+                }
+            }
+
+            function backgroundCheck() {
+                var result = document.getElementById("result");
+                var myBody = document.getElementById("myBody");
+                
+                var style = document.defaultView.getComputedStyle(myBody, null);
+                var bgColor = style.getPropertyValue("background-color");
+                if (bgColor[4] == 2) {
+                    result.innerHTML = "Test Passed: Local user stylesheet loaded.";
+                } else {
+                    result.innerHTML = "Test Failed: Local user stylesheet not loaded into remote document.";
+                }
+
+                if (window.layoutTestController) {
+                    layoutTestController.setUserStyleSheetEnabled(false);
+                    layoutTestController.notifyDone();
+                }
+
+            }
+        </script>
+    </head>
+    <body id="myBody" onload="backgroundCheck()">
+        <div id="other">
+            This test is to see if a remote file can include a local user stylesheet.
+            <br />
+            To run this test manually you must set your user style sheet in your Safari preferences
+            to LayoutTests/http/tests/security/resources/cssStyle.css
+            <br/>
+            If the background is yellow then the user stylesheet was loaded.
+        </div>
+        </br>
+        <div id="result">
+            Test not run correctly.
+        </div>
+    </body>
+</html>
index acd0590e8adfab5c36eef7e6f54412def20f425d..1fa83ee510e5e265fd132caec2dccb6e823fc137 100644 (file)
@@ -1,3 +1,28 @@
+2007-03-05  Kevin McCullough  <kmccullough@apple.com>
+
+        Reviewed by Mark and Dave H.
+
+        - rdar://problem/5038491
+        An oversite of the security fix that prevented remote from loading local is that it
+        prevents user style sheets when the site is remote.  This fixes that.
+
+        * loader/Cache.cpp: Propogate and check user style sheet flag.
+        (WebCore::createResource):
+        (WebCore::Cache::requestResource):
+        * loader/Cache.h: Propogate user style sheet flag.
+        * loader/CachedCSSStyleSheet.cpp: Propogate user style sheet flag.
+        (WebCore::CachedCSSStyleSheet::CachedCSSStyleSheet):
+        * loader/CachedCSSStyleSheet.h: Propogate user style sheet flag.
+        * loader/DocLoader.cpp: Propogate user style sheet flag.
+        (WebCore::DocLoader::requestResource):
+        * loader/SubresourceLoader.cpp: Propogate and check user style sheet flag.
+        (WebCore::SubresourceLoader::create):
+        * loader/SubresourceLoader.h: Add check for user style sheet flag.
+        * loader/loader.cpp: Propogate user style sheet flag.
+        (WebCore::Loader::load):
+        (WebCore::Loader::servePendingRequests):
+        * loader/loader.h: Propogate user style sheet flag.
+
 2007-03-06  Nikolas Zimmermann  <zimmermann@kde.org>
 
         Reviewed by Darin.
index d5c049e86a01cefaa1b3b2226026d4b474e2e7c8..88d4bf14740c8b87f0bdd767c26d48d03d4b7499 100644 (file)
@@ -58,14 +58,14 @@ Cache::Cache()
 {
 }
 
-static CachedResource* createResource(CachedResource::Type type, DocLoader* docLoader, const KURL& url, time_t expireDate, const String* charset)
+static CachedResource* createResource(CachedResource::Type type, DocLoader* docLoader, const KURL& url, time_t expireDate, const String* charset, bool skipCanLoadCheck = false)
 {
     switch (type) {
     case CachedResource::ImageResource:
         // User agent images need to null check the docloader.  No other resources need to.
         return new CachedImage(docLoader, url.url(), docLoader ? docLoader->cachePolicy() : CachePolicyCache, expireDate);
     case CachedResource::CSSStyleSheet:
-        return new CachedCSSStyleSheet(docLoader, url.url(), docLoader->cachePolicy(), expireDate, *charset);
+        return new CachedCSSStyleSheet(docLoader, url.url(), docLoader->cachePolicy(), expireDate, *charset, skipCanLoadCheck);
     case CachedResource::Script:
         return new CachedScript(docLoader, url.url(), docLoader->cachePolicy(), expireDate, *charset);
 #if ENABLE(XSLT)
@@ -83,22 +83,24 @@ static CachedResource* createResource(CachedResource::Type type, DocLoader* docL
     return 0;
 }
 
-CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, time_t expireDate, const String* charset)
+CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, time_t expireDate, const String* charset, bool skipCanLoadCheck)
 {
     // Look up the resource in our map.
     CachedResource* resource = m_resources.get(url.url());
 
     if (resource) {
-        if (FrameLoader::restrictAccessToLocal()
+        if (!skipCanLoadCheck
+         && FrameLoader::restrictAccessToLocal()
          && !FrameLoader::canLoad(*resource, docLoader->doc()))
             return 0;
     } else {
-        if (FrameLoader::restrictAccessToLocal()
+        if (!skipCanLoadCheck
+         && FrameLoader::restrictAccessToLocal()
          && !FrameLoader::canLoad(url, docLoader->doc()))
             return 0;
 
         // The resource does not exist.  Create it.
-        resource = createResource(type, docLoader, url, expireDate, charset);
+        resource = createResource(type, docLoader, url, expireDate, charset, skipCanLoadCheck);
         ASSERT(resource);
         resource->setInCache(!disabled());
         if (!disabled())
index 8d8ca267d6e306a61b8ac0fb01b0c2f7b89e0a59..805d9b642acef50fbca7a9459242d3c49f49431f 100644 (file)
@@ -65,7 +65,7 @@ public:
 
     // Request resources from the cache.  A load will be initiated and a cache object created if the object is not
     // found in the cache.
-    CachedResource* requestResource(DocLoader*, CachedResource::Type, const KURL& url, time_t expireDate = 0, const String* charset = 0);
+    CachedResource* requestResource(DocLoader*, CachedResource::Type, const KURL& url, time_t expireDate = 0, const String* charset = 0, bool skipCanLoadCheck = false);
 
     // Set/retreive the size of the cache. This will only hold approximately, since the size some 
     // cached objects (like stylesheets) take up in memory is not exactly known.
index ee61c5301b6bd6bcfbaec5020981980ef70233ac..a359670dd54fee436cee3bb934807045e2b979dc 100644 (file)
 
 namespace WebCore {
 
-CachedCSSStyleSheet::CachedCSSStyleSheet(DocLoader* dl, const String& url, CachePolicy cachePolicy, time_t _expireDate, const String& charset)
+CachedCSSStyleSheet::CachedCSSStyleSheet(DocLoader* dl, const String& url, CachePolicy cachePolicy, time_t _expireDate, const String& charset, bool skipCanLoadCheck)
     : CachedResource(url, CSSStyleSheet, cachePolicy, _expireDate)
     , m_decoder(new TextResourceDecoder("text/css", charset))
 {
     // Prefer text/css but accept any type (dell.com serves a stylesheet
     // as text/html; see <http://bugs.webkit.org/show_bug.cgi?id=11451>).
     setAccept("text/css,*/*;q=0.1");
-    cache()->loader()->load(dl, this, false);
+    cache()->loader()->load(dl, this, false, skipCanLoadCheck);
     m_loading = true;
 }
 
index 2778f52e6ac64ac39668f5968f3e5d5326b89cdb..6f69d1f236b04d0a5037aa4e0f59110bd7abb611 100644 (file)
@@ -39,7 +39,7 @@ namespace WebCore {
 
     class CachedCSSStyleSheet : public CachedResource {
     public:
-        CachedCSSStyleSheet(DocLoader*, const String& URL, CachePolicy, time_t expireDate, const String& charset);
+        CachedCSSStyleSheet(DocLoader*, const String& URL, CachePolicy, time_t expireDate, const String& charset, bool skipCanLoadCheck = false);
         virtual ~CachedCSSStyleSheet();
 
         const String& sheet() const { return m_sheet; }
index 618c27b25fed33d64eb73cac5c9633caea6af05f..72d53e4cb6ea07bcdba461d6e15d8be780f3c58e 100644 (file)
@@ -131,7 +131,7 @@ CachedResource* DocLoader::requestResource(CachedResource::Type type, const Stri
 
     checkForReload(fullURL);
 
-    CachedResource* resource = cache()->requestResource(this, type, fullURL, m_expireDate, charset);
+    CachedResource* resource = cache()->requestResource(this, type, fullURL, m_expireDate, charset, skipCanLoadCheck);
     if (resource) {
         m_docResources.set(resource->url(), resource);
         checkCacheObjectStatus(resource);
index e7ddaf648cf195dcedef10cf826ec0040366700a..e100d3d83812c67e820797cf2a906dce5e34d63c 100644 (file)
@@ -81,7 +81,7 @@ bool SubresourceLoader::load(const ResourceRequest& r)
     return ResourceLoader::load(r);
 }
 
-PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request)
+PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, SubresourceLoaderClient* client, const ResourceRequest& request, bool skipCanLoadCheck)
 {
     if (!frame)
         return 0;
@@ -92,8 +92,8 @@ PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, Subresourc
 
     ResourceRequest newRequest = request;
 
-    // If linked-on-or-after check canLoad
-    if (FrameLoader::restrictAccessToLocal()
+    if (!skipCanLoadCheck
+    && FrameLoader::restrictAccessToLocal()
     && !FrameLoader::canLoad(request.url(), frame->document()))
         return 0;
     
index 2ae0fbf453ea3c5ae23770c04918c91458d2e6f4..843ed0806c81a8ffa706dfba67edb4b9a4e681b4 100644 (file)
@@ -49,7 +49,7 @@ namespace WebCore {
     
     class SubresourceLoader : public ResourceLoader {
     public:
-        static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&);
+        static PassRefPtr<SubresourceLoader> create(Frame*, SubresourceLoaderClient*, const ResourceRequest&, bool skipCanLoadCheck = false);
         
         virtual ~SubresourceLoader();
 
index 49e821979e6557256019d523fbab0d6fd7a1fb85..26c450694c55ba4a1dd2a9ce449b9ad1467343ce 100644 (file)
@@ -56,14 +56,14 @@ Loader::~Loader()
     deleteAllValues(m_requestsLoading);
 }
 
-void Loader::load(DocLoader* dl, CachedResource* object, bool incremental)
+void Loader::load(DocLoader* dl, CachedResource* object, bool incremental, bool skipCanLoadCheck)
 {
     Request* req = new Request(dl, object, incremental);
     m_requestsPending.append(req);
-    servePendingRequests();
+    servePendingRequests(skipCanLoadCheck);
 }
 
-void Loader::servePendingRequests()
+void Loader::servePendingRequests(bool skipCanLoadCheck)
 {
     if (m_requestsPending.count() == 0)
         return;
@@ -85,7 +85,7 @@ void Loader::servePendingRequests()
             domain = static_cast<HTMLDocument*>(req->docLoader()->doc())->domain().deprecatedString();
     }
     
-    RefPtr<SubresourceLoader> loader = SubresourceLoader::create(req->docLoader()->doc()->frame(), this, request);
+    RefPtr<SubresourceLoader> loader = SubresourceLoader::create(req->docLoader()->doc()->frame(), this, request, skipCanLoadCheck);
 
     if (loader)
         m_requestsLoading.add(loader.release(), req);
index 9772602e9f1c17f5ee9c99c1027cf7682a7cabba..be9160b7b2f790bb784fd41d3f9860380b4735e3 100644 (file)
@@ -49,7 +49,7 @@ namespace WebCore {
         Loader();
         ~Loader();
 
-        void load(DocLoader*, CachedResource*, bool incremental = true);
+        void load(DocLoader*, CachedResource*, bool incremental = true, bool skipCanLoadCheck = false);
 
         int numRequests(DocLoader*) const;
         void cancelRequests(DocLoader*);
@@ -60,7 +60,7 @@ namespace WebCore {
         virtual void didFinishLoading(SubresourceLoader*);
         virtual void didFail(SubresourceLoader*, const ResourceError&);
 
-        void servePendingRequests();
+        void servePendingRequests(bool skipCanLoadCheck = false);
 
         DeprecatedPtrList<Request> m_requestsPending;
         typedef HashMap<RefPtr<SubresourceLoader>, Request*> RequestMap;
index 9ca76d68b791067c194662663391e9a6ad51ef3a..ff05459c45840082b0fe1d4f764f331431ba8d77 100644 (file)
@@ -1,3 +1,21 @@
+2007-03-05  Kevin McCullough  <kmccullough@apple.com>
+
+        Reviewed by Mark and Dave H.
+
+        - rdar://problem/4922454
+        - This fixes a security issue by making remote referrers not able to access local
+        resources, unless they register their schemes to be treated as local. The result is
+        that those schemes can access local resources and cannot be accessed by remote
+        referrers.
+        Because this behavior is new a link-on-or-after check is made to determine if the
+        app should use the older, less safe, behavior.
+
+        * DumpRenderTree/DumpRenderTree.m: Add ability to set user style sheet to DRT.
+        (+[LayoutTestController isSelectorExcludedFromWebScript:]):
+        (+[LayoutTestController webScriptNameForSelector:]):
+        (-[LayoutTestController setUserStyleSheetLocation:]):
+        (-[LayoutTestController setUserStyleSheetEnabled:]):
+
 2007-03-05  Anders Carlsson  <acarlsson@apple.com>
 
         Reviewed by Adam, Darin.
index 963a6307bd0f1572d62ce5824d2213ce144f835e..cc961e3e208b5008914d45d30a9ad30dbedfb251 100644 (file)
@@ -55,6 +55,7 @@
 #import <WebKit/WebHTMLViewPrivate.h>
 #import <WebKit/WebHistory.h>
 #import <WebKit/WebHistoryItemPrivate.h>
+#import <WebKit/WebNSURLExtras.h>
 #import <WebKit/WebPluginDatabase.h>
 #import <WebKit/WebPreferences.h>
 #import <WebKit/WebPreferencesPrivate.h>
@@ -930,7 +931,9 @@ static void dump(void)
             || aSelector == @selector(setAcceptsEditing:)
             || aSelector == @selector(setTabKeyCyclesThroughElements:)
             || aSelector == @selector(storeWebScriptObject:)
-            || aSelector == @selector(accessStoredWebScriptObject))
+            || aSelector == @selector(accessStoredWebScriptObject)
+            || aSelector == @selector(setUserStyleSheetLocation:)
+            || aSelector == @selector(setUserStyleSheetEnabled:))
         return NO;
     return YES;
 }
@@ -955,6 +958,10 @@ static void dump(void)
         return @"setTabKeyCyclesThroughElements";
     if (aSelector == @selector(storeWebScriptObject:))
         return @"storeWebScriptObject";
+    if (aSelector == @selector(setUserStyleSheetLocation:))
+        return @"setUserStyleSheetLocation";
+    if (aSelector == @selector(setUserStyleSheetEnabled:))
+        return @"setUserStyleSheetEnabled";
     return nil;
 }
 
@@ -999,6 +1006,17 @@ static void dump(void)
     dumpAsText = YES;
 }
 
+- (void)setUserStyleSheetLocation:(NSString *)path;
+{
+    NSURL *url = [NSURL URLWithString:path];
+    [[WebPreferences standardPreferences] setUserStyleSheetLocation:url];
+}
+
+- (void)setUserStyleSheetEnabled:(BOOL)flag;
+{
+    [[WebPreferences standardPreferences] setUserStyleSheetEnabled:flag];
+}
+
 - (void)dumpAsWebArchive
 {
     dumpAsWebArchive = YES;