A canvas should not be tainted if it draws a data URL SVGImage with a <foreignObject>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Jan 2018 00:35:35 +0000 (00:35 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Jan 2018 00:35:35 +0000 (00:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180301

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2018-01-08
Reviewed by Dean Jackson.

Source/WebCore:

Don't taint the canvas if it draws a data URL SVGImage with a <foreignObject>.
There should not be a cross-origin data leak in this case.

Tests: svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted.html
       svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted.html
       svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted.html

* html/ImageBitmap.cpp:
(WebCore::taintsOrigin):
* html/canvas/CanvasRenderingContext.cpp:
(WebCore::CanvasRenderingContext::wouldTaintOrigin):

LayoutTests:

* svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted-expected.txt: Added.
* svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted.html: Added.
* svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted-expected.txt: Added.
* svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted.html: Added.
* svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted-expected.txt: Added.
* svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted-expected.txt [new file with mode: 0644]
LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted.html [new file with mode: 0644]
LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted-expected.txt [new file with mode: 0644]
LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted.html [new file with mode: 0644]
LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted-expected.txt [new file with mode: 0644]
LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/ImageBitmap.cpp
Source/WebCore/html/canvas/CanvasRenderingContext.cpp

index 8487925..1bda487 100644 (file)
@@ -1,3 +1,17 @@
+2018-01-08  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        A canvas should not be tainted if it draws a data URL SVGImage with a <foreignObject>
+        https://bugs.webkit.org/show_bug.cgi?id=180301
+
+        Reviewed by Dean Jackson.
+
+        * svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted-expected.txt: Added.
+        * svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted.html: Added.
+        * svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted-expected.txt: Added.
+        * svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted.html: Added.
+        * svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted-expected.txt: Added.
+        * svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted.html: Added.
+
 2018-01-08  Matt Lewis  <jlewis3@apple.com>
 
         Marked imported/w3c/web-platform-tests/service-workers/service-worker/register-closed-window.https.html as flaky.
diff --git a/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted-expected.txt b/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted-expected.txt
new file mode 100644 (file)
index 0000000..4df50c1
--- /dev/null
@@ -0,0 +1,10 @@
+Canvas should not be tainted if a data url image with a data url <feimage> which has a <foreignObject> is drawn into the canvas.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.ctx.getImageData(0, 0, 1, 1) did not throw exception.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted.html b/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted.html
new file mode 100644 (file)
index 0000000..31e5efd
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<head>
+    <script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+    <canvas></canvas>
+    <script type="text/javascript">
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        jsTestIsAsync = true;
+        description("Canvas should not be tainted if a data url image with a data url &lt;feimage&gt; which has a &lt;foreignObject&gt; is drawn into the canvas.");
+
+        var data = "data:image/svg+xml;charset=utf-8,"
+                + '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px">'
+                + '    <defs>'
+                + '        <filter id="image">'
+                + '            <feImage xlink:href="data:image/svg+xml;charset=utf-8;base64,'
+                + '                PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDBweCIgaGVpZ2h0PSIxMDBweCI+DQog'
+                + '                ICAgPGZvcmVpZ25PYmplY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSI+DQogICAgICAgIDxkaXYgeG1sbnM9Imh0dHA6'
+                + '                Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJ3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlOyBiYWNrZ3JvdW5kLWNv'
+                + '                bG9yOiBncmVlbjsiPjwvZGl2Pg0KICAgIDwvZm9yZWlnbk9iamVjdD4nDQo8L3N2Zz4NCg0K">'
+                + '            </feImage>'
+                + '        </filter>'
+                + '    </defs>'
+                + '    <rect width="100%" height="100%" style="filter:url(#image);"/>'
+                + '</svg>';
+
+        var svg = new Image();
+        svg.onload = function() {
+            var canvas = document.querySelector('canvas');
+            window.ctx = canvas.getContext('2d');
+
+            // Wait for the data uri in the image to load.
+            setTimeout(function() {
+                ctx.drawImage(svg, 0, 0);
+                shouldNotThrow("window.ctx.getImageData(0, 0, 1, 1)");
+                finishJSTest();
+            }, 50);
+        }
+        svg.src = data;
+    </script>
+    <script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted-expected.txt b/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted-expected.txt
new file mode 100644 (file)
index 0000000..34405a3
--- /dev/null
@@ -0,0 +1,10 @@
+Canvas should not be tainted if a data url image with a <foreignObject> is drawn into the canvas.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.ctx.getImageData(0, 0, 1, 1) did not throw exception.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted.html b/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted.html
new file mode 100644 (file)
index 0000000..94fb9a5
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<head>
+    <script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+    <canvas></canvas>
+    <script type="text/javascript">
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        jsTestIsAsync = true;
+        description("Canvas should not be tainted if a data url image with a &lt;foreignObject&gt; is drawn into the canvas.");
+
+        var data = "data:image/svg+xml;charset=utf-8,"
+                + '<svg xmlns="http://www.w3.org/2000/svg">'
+                + '    <foreignObject width="100%" height="100%">'
+                + '        <div xmlns="http://www.w3.org/1999/xhtml" style="width:100px; height: 100px; background-color: green;"></div>'
+                + '    </foreignObject>'
+                + '</svg>';
+
+        var svg = new Image();
+        svg.onload = function() {
+            var canvas = document.querySelector('canvas');
+            window.ctx = canvas.getContext('2d');
+            ctx.drawImage(svg, 0, 0);
+            shouldNotThrow("window.ctx.getImageData(0, 0, 1, 1)");
+            finishJSTest();
+        }
+        svg.src = data;
+    </script>
+    <script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted-expected.txt b/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted-expected.txt
new file mode 100644 (file)
index 0000000..e994066
--- /dev/null
@@ -0,0 +1,10 @@
+Canvas should not be tainted if a data url image with a data url <image> which has a <foreignObject> is drawn into the canvas.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.ctx.getImageData(0, 0, 1, 1) did not throw exception.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted.html b/LayoutTests/svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted.html
new file mode 100644 (file)
index 0000000..e40f625
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<head>
+    <script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+    <canvas></canvas>
+    <script type="text/javascript">
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        jsTestIsAsync = true;
+        description("Canvas should not be tainted if a data url image with a data url &lt;image&gt; which has a &lt;foreignObject&gt; is drawn into the canvas.");
+
+        var data = "data:image/svg+xml;charset=utf-8,"
+                + '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px">'
+                + '    <image width="100" height="100" xlink:href="data:image/svg+xml;charset=utf-8;base64,'
+                + '        PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDBweCIgaGVpZ2h0PSIxMDBweCI+DQog'
+                + '        ICAgPGZvcmVpZ25PYmplY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSI+DQogICAgICAgIDxkaXYgeG1sbnM9Imh0dHA6'
+                + '        Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJ3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlOyBiYWNrZ3JvdW5kLWNv'
+                + '        bG9yOiBncmVlbjsiPjwvZGl2Pg0KICAgIDwvZm9yZWlnbk9iamVjdD4nDQo8L3N2Zz4NCg0K">'
+                + '    </image>'
+                + '</svg>';
+
+        var svg = new Image();
+        svg.onload = function() {
+            var canvas = document.querySelector('canvas');
+            window.ctx = canvas.getContext('2d');
+
+            // Wait for the data uri in the image to load.
+            setTimeout(function() {
+                ctx.drawImage(svg, 0, 0);
+                shouldNotThrow("window.ctx.getImageData(0, 0, 1, 1)");
+                finishJSTest();
+            }, 50);
+        }
+        svg.src = data;
+    </script>
+    <script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index bcc8d16..b5ae76d 100644 (file)
@@ -1,3 +1,22 @@
+2018-01-08  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        A canvas should not be tainted if it draws a data URL SVGImage with a <foreignObject>
+        https://bugs.webkit.org/show_bug.cgi?id=180301
+
+        Reviewed by Dean Jackson.
+
+        Don't taint the canvas if it draws a data URL SVGImage with a <foreignObject>.
+        There should not be a cross-origin data leak in this case.
+
+        Tests: svg/as-image/svg-canvas-data-url-svg-with-feimage-not-tainted.html
+               svg/as-image/svg-canvas-data-url-svg-with-foreign-object-not-tainted.html
+               svg/as-image/svg-canvas-data-url-svg-with-image-not-tainted.html
+
+        * html/ImageBitmap.cpp:
+        (WebCore::taintsOrigin):
+        * html/canvas/CanvasRenderingContext.cpp:
+        (WebCore::CanvasRenderingContext::wouldTaintOrigin):
+
 2018-01-08  Don Olmstead  <don.olmstead@sony.com>
 
         Simplify platform checks in Graphics Context
index 30ba83c..72d9339 100644 (file)
@@ -102,6 +102,9 @@ static bool taintsOrigin(CachedImage& cachedImage)
     if (!image)
         return false;
 
+    if (image->sourceURL().protocolIsData())
+        return false;
+
     if (!image->hasSingleSecurityOrigin())
         return true;
 
index 2a6c768..8582a06 100644 (file)
@@ -81,6 +81,9 @@ bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* element)
     if (!image)
         return false;
 
+    if (image->sourceURL().protocolIsData())
+        return false;
+    
     if (!image->hasSingleSecurityOrigin())
         return true;