Title: [175074] trunk
Revision
175074
Author
[email protected]
Date
2014-10-22 16:43:11 -0700 (Wed, 22 Oct 2014)

Log Message

SVG loaded through html <img> can't request to load any external resources.
https://bugs.webkit.org/show_bug.cgi?id=137762.

Patch by Said Abou-Hallawa <[email protected]> on 2014-10-22
Reviewed by Daniel Bates.

Source/WebCore:

SVG images have unique security rules that prevent them from loading any external
resources. This patch enforces these rules in CachedResourceLoader::canRequest for
all non-data-uri resources.

The fix and the tests are ported but modified a little from the chromium fix:
http://src.chromium.org/viewvc/blink?view=rev&rev=176084

Test: http/tests/security/svg-image-with-cached-remote-image.html
      http/tests/security/svg-image-with-css-cross-domain.html

For the SVG image, prevent loading any external sub-resource except for data urls.
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::canRequest):

LayoutTests:

Ensure that SVG images, which are loaded through the <img> tag or through the
CSS background image, cannot load any external sub-resource except for data-
URL resources (though this doesn't work at the time of writing, see bug #137941).
Also ensure the same rule is enforced on cached resources.

The tests are ported but modified a little from the chromium fix:
http://src.chromium.org/viewvc/blink?view=rev&rev=176084

Set the circle background to orange
* http/tests/security/resources/image-with-css-cross-domain-circle.css: Added.
(circle):

Set the circle stroke-width = 2 and the circle stroke = red
* http/tests/security/resources/image-with-css-cross-domain-circle2.css: Added.
(circle):

This svg references the two css files: one is relative path and the other is absolute path
* http/tests/security/resources/image-with-css-cross-domain.svg: Added.

This svg references an external image.
* http/tests/security/resources/image-with-remote-image.svg: Added.

A helper css which sets the formatting style for some html tags
* http/tests/security/svg-image-with-css-cross-domain.css: Added.
(span):
(span.circle-css-cross-domain):
(embed):
(iframe):

Test the svg which is referenced as a cached image by an <object> tag, does not load
external sub-resource.
* http/tests/security/svg-image-with-cached-remote-image-expected.html: Added.
* http/tests/security/svg-image-with-cached-remote-image.html: Added.

Test loading sub-resources for an svg which is included in the html by different ways
and which references external css files.
Ensure the image object does not load any external sub-resources.
* http/tests/security/svg-image-with-css-cross-domain-expected.html: Added.
* http/tests/security/svg-image-with-css-cross-domain.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (175073 => 175074)


--- trunk/LayoutTests/ChangeLog	2014-10-22 23:27:27 UTC (rev 175073)
+++ trunk/LayoutTests/ChangeLog	2014-10-22 23:43:11 UTC (rev 175074)
@@ -1,3 +1,50 @@
+2014-10-22  Said Abou-Hallawa  <[email protected]>
+
+        SVG loaded through html <img> can't request to load any external resources.
+        https://bugs.webkit.org/show_bug.cgi?id=137762.
+
+        Reviewed by Daniel Bates.
+
+        Ensure that SVG images, which are loaded through the <img> tag or through the
+        CSS background image, cannot load any external sub-resource except for data-
+        URL resources (though this doesn't work at the time of writing, see bug #137941).
+        Also ensure the same rule is enforced on cached resources.
+
+        The tests are ported but modified a little from the chromium fix:
+        http://src.chromium.org/viewvc/blink?view=rev&rev=176084
+
+        Set the circle background to orange
+        * http/tests/security/resources/image-with-css-cross-domain-circle.css: Added.
+        (circle):
+
+        Set the circle stroke-width = 2 and the circle stroke = red
+        * http/tests/security/resources/image-with-css-cross-domain-circle2.css: Added.
+        (circle):
+
+        This svg references the two css files: one is relative path and the other is absolute path
+        * http/tests/security/resources/image-with-css-cross-domain.svg: Added.
+
+        This svg references an external image.
+        * http/tests/security/resources/image-with-remote-image.svg: Added.
+
+        A helper css which sets the formatting style for some html tags
+        * http/tests/security/svg-image-with-css-cross-domain.css: Added.
+        (span):
+        (span.circle-css-cross-domain):
+        (embed):
+        (iframe):
+
+        Test the svg which is referenced as a cached image by an <object> tag, does not load
+        external sub-resource.
+        * http/tests/security/svg-image-with-cached-remote-image-expected.html: Added.
+        * http/tests/security/svg-image-with-cached-remote-image.html: Added.
+
+        Test loading sub-resources for an svg which is included in the html by different ways
+        and which references external css files.
+        Ensure the image object does not load any external sub-resources.
+        * http/tests/security/svg-image-with-css-cross-domain-expected.html: Added.
+        * http/tests/security/svg-image-with-css-cross-domain.html: Added.
+
 2014-10-21  Ada Chan  <[email protected]>
 
         MediaPlayerPrivateAVFoundation::hasAudio() returns false even when there is an audible AVMediaSelectionOption selected

Added: trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain-circle.css (0 => 175074)


--- trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain-circle.css	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain-circle.css	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,3 @@
+circle {
+    fill: orange;
+}

Added: trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain-circle2.css (0 => 175074)


--- trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain-circle2.css	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain-circle2.css	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,4 @@
+circle {
+    stroke: red;
+    stroke-width: 2;
+}

Added: trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain.svg (0 => 175074)


--- trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain.svg	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/image-with-css-cross-domain.svg	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml-stylesheet type="text/css" href=""
+<?xml-stylesheet type="text/css" href=""
+<svg xmlns="http://www.w3.org/2000/svg" width="68" height="68" viewBox="-34 -34 68 68" >
+  <circle cx="0" cy="0" r="24" fill="#c8c8c8"/>
+</svg>

Added: trunk/LayoutTests/http/tests/security/resources/image-with-remote-image.svg (0 => 175074)


--- trunk/LayoutTests/http/tests/security/resources/image-with-remote-image.svg	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/resources/image-with-remote-image.svg	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
+  <rect width="100%" height="100%" fill="#0f0"/>
+  <rect x="20%" y="20%" width="60%" height="60%" stroke-width="1" stroke="black" fill="transparent"/>
+  <image xlink:href="" x="20%" y="20%" width="60%" height="60%" _onload_="window.parent.notifyDidLoadSVG()"/>
+</svg>

Added: trunk/LayoutTests/http/tests/security/svg-image-with-cached-remote-image-expected.html (0 => 175074)


--- trunk/LayoutTests/http/tests/security/svg-image-with-cached-remote-image-expected.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/svg-image-with-cached-remote-image-expected.html	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<p>SVG loaded in &lt;img&gt; (should not see head of Abe Lincoln)</p>
+<svg width="100" height="100">
+  <rect width="100%" height="100%" fill="#0f0"/>
+  <rect x="20%" y="20%" width="60%" height="60%" stroke-width="1" stroke="black" fill="transparent"/>
+</svg>
+<br>
+<p>SVG loaded in &lt;object&gt; (should see head of Abe Lincoln)</p>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
+  <rect width="100%" height="100%" fill="#0f0"/>
+  <rect x="20%" y="20%" width="60%" height="60%" stroke-width="1" stroke="black" fill="transparent"/>
+  <image xlink:href="" x="20%" y="20%" width="60%" height="60%"/>
+</svg>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/svg-image-with-cached-remote-image.html (0 => 175074)


--- trunk/LayoutTests/http/tests/security/svg-image-with-cached-remote-image.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/svg-image-with-cached-remote-image.html	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script>
+  if (window.testRunner)
+    testRunner.waitUntilDone();
+
+  // Called from resources/image-with-remote-image.svg when loaded inside <object>.
+  function notifyDidLoadSVG() 
+  {
+    function done() 
+    {
+      if (window.testRunner)
+        testRunner.notifyDone();
+    }
+    var image = document.getElementById("non-interactive-SVG");
+    image._onload_ = done;
+    image.src = ""
+  }
+</script>
+</head>
+<body>
+  <p>SVG loaded in &lt;img&gt; (should not see head of Abe Lincoln)</p>
+  <img id="non-interactive-SVG" src="" width="100" height="100">
+  <br>
+  <p>SVG loaded in &lt;object&gt; (should see head of Abe Lincoln)</p>
+  <object id="interactive-SVG" data="" width="100" height="100"></object>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain-expected.html (0 => 175074)


--- trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain-expected.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain-expected.html	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <link rel="stylesheet" type="text/css" href=""
+  </head>
+  <body>
+    <h1>WebKit bug</h1>
+    <h3>SVG circle with same-origin and different-origin CSS</h3>
+    <p>Expected: 2 gray circles, 4 orange circles with red borders, 2 gray circle.</p>
+    <p>
+      <span class="image">
+        <svg height="68" width="68" viewBox="-34 -34 68 68">
+          <circle cx="0" cy="0" r="24" fill="#c8c8c8" />
+        </svg>
+      </span>
+      <span class="image">
+        <svg height="68" width="68" viewBox="-34 -34 68 68">
+          <circle cx="0" cy="0" r="24" fill="#c8c8c8" />
+        </svg>
+      </span>
+      <span class="image">
+        <svg height="68" width="68" viewBox="-34 -34 68 68">
+          <circle cx="0" cy="0" r="24" stroke="red" stroke-width="2" fill="orange" />
+        </svg>	
+      </span>
+      <span class="image">
+        <svg height="68" width="68" viewBox="-34 -34 68 68">
+          <circle cx="0" cy="0" r="24" stroke="red" stroke-width="2" fill="orange" />
+        </svg>	
+      </span>
+      <span class="image">
+        <svg height="68" width="68" viewBox="-34 -34 68 68">
+          <circle cx="0" cy="0" r="24" stroke="red" stroke-width="2" fill="orange" />
+        </svg>	
+      </span>
+      <span class="image">
+        <svg height="68" width="68" viewBox="-34 -34 68 68">
+          <circle cx="0" cy="0" r="24" stroke="red" stroke-width="2" fill="orange" />
+        </svg>	
+      </span>
+      <span class="image">
+        <svg height="68" width="68" viewBox="-34 -34 68 68">
+          <circle cx="0" cy="0" r="24" fill="#c8c8c8" />
+        </svg>
+      </span>
+      <span class="image">
+        <svg height="68" width="68" viewBox="-34 -34 68 68">
+          <circle cx="0" cy="0" r="24" fill="#c8c8c8" />
+        </svg>
+      </span>
+    </p>
+  </body>
+</html>

Added: trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain.css (0 => 175074)


--- trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain.css	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain.css	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,17 @@
+span {
+  display: inline-block;
+  height: 68px;
+  width: 68px;
+}
+
+span.circle-css-cross-domain {
+  background-image: url('resources/image-with-css-cross-domain.svg');
+}
+
+embed {
+  display: inline-block;
+}
+
+iframe {
+  border-width: 0px;
+}

Added: trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain.html (0 => 175074)


--- trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/svg-image-with-css-cross-domain.html	2014-10-22 23:43:11 UTC (rev 175074)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <link rel="stylesheet" type="text/css" href=""
+  </head>
+  <body>
+    <h1>WebKit bug</h1>
+    <h3>SVG circle with same-origin and different-origin CSS</h3>
+    <p>Expected: 2 gray circles, 4 orange circles with red borders, 2 gray circle.</p>
+    <p>
+      <span class="image"><img src="" alt="circle" width="68" height="68"/></span>
+      <span class="image circle-css-cross-domain"></span>
+      <object data="" type="image/svg+xml" width="68" height="68"></object>
+      <embed src="" type="image/svg+xml" width="68" height="68"></embed>
+      <iframe src="" width="68" height="68"></iframe>
+      <iframe src="" width="68" height="68" sandbox=""></iframe>
+      <span class="image"><img width="68" height="68" alt="circle" src=""
+	  <span class="image">
+        <?xml version="1.0" encoding="UTF-8" standalone="no"?>
+        <?xml-stylesheet type="text/css" href=""
+        <?xml-stylesheet type="text/css" href=""
+        <svg xmlns="http://www.w3.org/2000/svg" width="68" height="68" viewBox="-34 -34 68 68" version="1.1">
+          <circle cx="0" cy="0" r="24" fill="#c8c8c8"/>
+        </svg>
+      </span>
+    </p>
+  </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (175073 => 175074)


--- trunk/Source/WebCore/ChangeLog	2014-10-22 23:27:27 UTC (rev 175073)
+++ trunk/Source/WebCore/ChangeLog	2014-10-22 23:43:11 UTC (rev 175074)
@@ -1,3 +1,24 @@
+2014-10-22  Said Abou-Hallawa  <[email protected]>
+
+        SVG loaded through html <img> can't request to load any external resources.
+        https://bugs.webkit.org/show_bug.cgi?id=137762.
+
+        Reviewed by Daniel Bates.
+
+        SVG images have unique security rules that prevent them from loading any external
+        resources. This patch enforces these rules in CachedResourceLoader::canRequest for
+        all non-data-uri resources.
+
+        The fix and the tests are ported but modified a little from the chromium fix:
+        http://src.chromium.org/viewvc/blink?view=rev&rev=176084
+
+        Test: http/tests/security/svg-image-with-cached-remote-image.html
+              http/tests/security/svg-image-with-css-cross-domain.html
+
+        For the SVG image, prevent loading any external sub-resource except for data urls.
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::CachedResourceLoader::canRequest):
+
 2014-10-21  Ada Chan  <[email protected]>
 
         MediaPlayerPrivateAVFoundation::hasAudio() returns false even when there is an audible AVMediaSelectionOption selected

Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp (175073 => 175074)


--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp	2014-10-22 23:27:27 UTC (rev 175073)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp	2014-10-22 23:43:11 UTC (rev 175074)
@@ -35,6 +35,8 @@
 #include "CachedResourceRequest.h"
 #include "CachedScript.h"
 #include "CachedXSLStyleSheet.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
 #include "ContentSecurityPolicy.h"
 #include "DOMWindow.h"
 #include "Document.h"
@@ -379,6 +381,12 @@
 #endif
     }
 
+    // SVG Images have unique security rules that prevent all subresource requests except for data urls.
+    if (type != CachedResource::MainResource && frame() && frame()->page()) {
+        if (frame()->page()->chrome().client().isSVGImageChromeClient() && !url.protocolIsData())
+            return false;
+    }
+
     // Last of all, check for insecure content. We do this last so that when
     // folks block insecure content with a CSP policy, they don't get a warning.
     // They'll still get a warning in the console about CSP blocking the load.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to