Restrict SVG filters to accessible security origins
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 May 2017 23:49:41 +0000 (23:49 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 May 2017 23:49:41 +0000 (23:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=118689
<rdar://problem/27362159>

Reviewed by Brent Fulgham.

Source/WebCore:

Certain SVG filters should only be allowed to operate
on content that is has SecurityOrigin access to. Implement
this by including a flag in PaintInfo and LayerPaintingInfo,
and have RenderWidget make sure the documents have acceptable
SecurityOrigins as it goes to paint.

This could be used as the first step in a "safe painting"
strategy, allowing some content to be rendered into a
canvas or via the element() CSS function... but it is only
a small first step.

Test: http/tests/css/filters-on-iframes.html

* page/FrameView.cpp:
(WebCore::FrameView::paintContents):
* page/FrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::paint):
* platform/ScrollView.h:
* platform/Scrollbar.cpp:
(WebCore::Scrollbar::paint):
* platform/Scrollbar.h:
* platform/Widget.h:
* platform/graphics/filters/FilterOperation.h:
(WebCore::FilterOperation::shouldBeRestrictedBySecurityOrigin):
* platform/graphics/filters/FilterOperations.cpp:
(WebCore::FilterOperations::hasFilterThatShouldBeRestrictedBySecurityOrigin):
* platform/graphics/filters/FilterOperations.h:
* platform/mac/WidgetMac.mm:
(WebCore::Widget::paint):
* rendering/FilterEffectRenderer.cpp:
(WebCore::FilterEffectRenderer::build):
* rendering/FilterEffectRenderer.h:
* rendering/PaintInfo.h:
(WebCore::PaintInfo::PaintInfo):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paint):
(WebCore::RenderLayer::setupFilters):
(WebCore::RenderLayer::paintForegroundForFragmentsWithPhase):
* rendering/RenderLayer.h:
* rendering/RenderScrollbar.cpp:
(WebCore::RenderScrollbar::paint):
* rendering/RenderScrollbar.h:
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::paintContents):

Source/WebKit2:

Update parameter lists.

* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::paint):
* WebProcess/Plugins/PluginView.h:

LayoutTests:

Add a test that shows safe frames, unsafe frames, and
then a safe frame that itself has an unsafe frame, to
show that the security requirements are being forwarded
down the tree.

* http/tests/css/filters-on-iframes-expected.html: Added.
* http/tests/css/filters-on-iframes.html: Added.
* http/tests/css/resources/blank.html: Added.
* http/tests/css/resources/references-external.html: Added.
* http/tests/css/resources/solid-red.html: Added.

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

29 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/css/filters-on-iframes-expected.html [new file with mode: 0644]
LayoutTests/http/tests/css/filters-on-iframes.html [new file with mode: 0644]
LayoutTests/http/tests/css/resources/blank.html [new file with mode: 0644]
LayoutTests/http/tests/css/resources/references-external.html [new file with mode: 0644]
LayoutTests/http/tests/css/resources/solid-red.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/platform/ScrollView.cpp
Source/WebCore/platform/ScrollView.h
Source/WebCore/platform/Scrollbar.cpp
Source/WebCore/platform/Scrollbar.h
Source/WebCore/platform/Widget.h
Source/WebCore/platform/graphics/filters/FilterOperation.h
Source/WebCore/platform/graphics/filters/FilterOperations.cpp
Source/WebCore/platform/graphics/filters/FilterOperations.h
Source/WebCore/platform/mac/WidgetMac.mm
Source/WebCore/rendering/FilterEffectRenderer.cpp
Source/WebCore/rendering/FilterEffectRenderer.h
Source/WebCore/rendering/PaintInfo.h
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderScrollbar.cpp
Source/WebCore/rendering/RenderScrollbar.h
Source/WebCore/rendering/RenderWidget.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Plugins/PluginView.cpp
Source/WebKit2/WebProcess/Plugins/PluginView.h

index 6c114c1..86db984 100644 (file)
@@ -1,3 +1,22 @@
+2017-05-05  Dean Jackson  <dino@apple.com>
+
+        Restrict SVG filters to accessible security origins
+        https://bugs.webkit.org/show_bug.cgi?id=118689
+        <rdar://problem/27362159>
+
+        Reviewed by Brent Fulgham.
+
+        Add a test that shows safe frames, unsafe frames, and
+        then a safe frame that itself has an unsafe frame, to
+        show that the security requirements are being forwarded
+        down the tree.
+
+        * http/tests/css/filters-on-iframes-expected.html: Added.
+        * http/tests/css/filters-on-iframes.html: Added.
+        * http/tests/css/resources/blank.html: Added.
+        * http/tests/css/resources/references-external.html: Added.
+        * http/tests/css/resources/solid-red.html: Added.
+
 2017-05-05  Simon Fraser  <simon.fraser@apple.com>
 
         Make it possible to test rotation in iOS WebKitTestRunner
diff --git a/LayoutTests/http/tests/css/filters-on-iframes-expected.html b/LayoutTests/http/tests/css/filters-on-iframes-expected.html
new file mode 100644 (file)
index 0000000..7d12325
--- /dev/null
@@ -0,0 +1,40 @@
+<style>
+body {
+    margin: 0;
+    padding: 0;
+}
+iframe {
+    border: none;
+}
+div {
+    display: inline-block;
+}
+</style>
+
+<div>
+    <iframe src="resources/solid-red.html"></iframe>
+</div>
+
+<div class="filtered">
+    <iframe src="resources/solid-red.html"></iframe>
+</div>
+
+<br>
+
+<div>
+    <iframe src="resources/solid-red.html"></iframe>
+</div>
+
+<div class="filtered">
+    <iframe src="resources/blank.html"></iframe>
+</div>
+
+<br>
+
+<div>
+    <iframe src="resources/solid-red.html"></iframe>
+</div>
+
+<div class="filtered">
+    <iframe src="resources/blank.html"></iframe>
+</div>
diff --git a/LayoutTests/http/tests/css/filters-on-iframes.html b/LayoutTests/http/tests/css/filters-on-iframes.html
new file mode 100644 (file)
index 0000000..2af62b2
--- /dev/null
@@ -0,0 +1,54 @@
+<style>
+body {
+    margin: 0;
+    padding: 0;
+}
+iframe {
+    border: none;
+}
+div {
+    display: inline-block;
+}
+.filtered {
+    filter: url(#noop);
+}
+svg {
+    display: none;
+}
+</style>
+
+<div>
+    <iframe src="resources/solid-red.html"></iframe>
+</div>
+
+<div class="filtered">
+    <iframe src="resources/solid-red.html"></iframe>
+</div>
+
+<br>
+
+<div>
+    <iframe src="http://localhost:8000/css/resources/solid-red.html"></iframe>
+</div>
+
+<div class="filtered">
+    <iframe src="http://localhost:8000/css/resources/solid-red.html"></iframe>
+</div>
+
+<br>
+
+<div>
+    <iframe src="resources/references-external.html"></iframe>
+</div>
+
+<div class="filtered">
+    <iframe src="resources/references-external.html"></iframe>
+</div>
+
+<svg>
+    <defs>
+        <filter id="noop">
+            <feMorphology operator="dilate" in="SourceGraphic" radius="0"/>
+        </filter>
+    </defs>
+</svg>
diff --git a/LayoutTests/http/tests/css/resources/blank.html b/LayoutTests/http/tests/css/resources/blank.html
new file mode 100644 (file)
index 0000000..1b315cb
--- /dev/null
@@ -0,0 +1,5 @@
+<style>
+    body {
+        background-color: white;
+    }
+</style>
diff --git a/LayoutTests/http/tests/css/resources/references-external.html b/LayoutTests/http/tests/css/resources/references-external.html
new file mode 100644 (file)
index 0000000..dd6ec12
--- /dev/null
@@ -0,0 +1,11 @@
+<style>
+body {
+    margin: 0;
+    padding: 0;
+}
+
+iframe {
+    border: none;
+}
+</style>
+<iframe src="http://localhost:8000/css/resources/solid-red.html"></iframe>
diff --git a/LayoutTests/http/tests/css/resources/solid-red.html b/LayoutTests/http/tests/css/resources/solid-red.html
new file mode 100644 (file)
index 0000000..8ee73d7
--- /dev/null
@@ -0,0 +1,5 @@
+<style>
+    body {
+        background-color: red;
+    }
+</style>
index df15dbb..3c65750 100644 (file)
@@ -1,3 +1,57 @@
+2017-05-05  Dean Jackson  <dino@apple.com>
+
+        Restrict SVG filters to accessible security origins
+        https://bugs.webkit.org/show_bug.cgi?id=118689
+        <rdar://problem/27362159>
+
+        Reviewed by Brent Fulgham.
+
+        Certain SVG filters should only be allowed to operate
+        on content that is has SecurityOrigin access to. Implement
+        this by including a flag in PaintInfo and LayerPaintingInfo,
+        and have RenderWidget make sure the documents have acceptable
+        SecurityOrigins as it goes to paint.
+
+        This could be used as the first step in a "safe painting"
+        strategy, allowing some content to be rendered into a 
+        canvas or via the element() CSS function... but it is only
+        a small first step.
+
+        Test: http/tests/css/filters-on-iframes.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::paintContents):
+        * page/FrameView.h:
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::paint):
+        * platform/ScrollView.h:
+        * platform/Scrollbar.cpp:
+        (WebCore::Scrollbar::paint):
+        * platform/Scrollbar.h:
+        * platform/Widget.h:
+        * platform/graphics/filters/FilterOperation.h:
+        (WebCore::FilterOperation::shouldBeRestrictedBySecurityOrigin):
+        * platform/graphics/filters/FilterOperations.cpp:
+        (WebCore::FilterOperations::hasFilterThatShouldBeRestrictedBySecurityOrigin):
+        * platform/graphics/filters/FilterOperations.h:
+        * platform/mac/WidgetMac.mm:
+        (WebCore::Widget::paint):
+        * rendering/FilterEffectRenderer.cpp:
+        (WebCore::FilterEffectRenderer::build):
+        * rendering/FilterEffectRenderer.h:
+        * rendering/PaintInfo.h:
+        (WebCore::PaintInfo::PaintInfo):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paint):
+        (WebCore::RenderLayer::setupFilters):
+        (WebCore::RenderLayer::paintForegroundForFragmentsWithPhase):
+        * rendering/RenderLayer.h:
+        * rendering/RenderScrollbar.cpp:
+        (WebCore::RenderScrollbar::paint):
+        * rendering/RenderScrollbar.h:
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::paintContents):
+
 2017-05-05  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r216273.
index 6719e90..8122d77 100644 (file)
@@ -4419,7 +4419,7 @@ void FrameView::didPaintContents(GraphicsContext& context, const IntRect& dirtyR
     }
 }
 
-void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect)
+void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect, SecurityOriginPaintPolicy securityOriginPaintPolicy)
 {
 #ifndef NDEBUG
     bool fillWithRed;
@@ -4471,7 +4471,7 @@ void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect
     while (is<RenderInline>(renderer) && !downcast<RenderInline>(*renderer).firstLineBox())
         renderer = renderer->parent();
 
-    rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer);
+    rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer, 0, securityOriginPaintPolicy == SecurityOriginPaintPolicy::AnyOrigin ? RenderLayer::SecurityOriginPaintPolicy::AnyOrigin : RenderLayer::SecurityOriginPaintPolicy::AccessibleOriginOnly);
     if (rootLayer->containsDirtyOverlayScrollbars())
         rootLayer->paintOverlayScrollbars(context, dirtyRect, m_paintBehavior, renderer);
 
index b14fef3..cdb2fbe 100644 (file)
@@ -344,7 +344,7 @@ public:
     void addEmbeddedObjectToUpdate(RenderEmbeddedObject&);
     void removeEmbeddedObjectToUpdate(RenderEmbeddedObject&);
 
-    WEBCORE_EXPORT void paintContents(GraphicsContext&, const IntRect& dirtyRect) final;
+    WEBCORE_EXPORT void paintContents(GraphicsContext&, const IntRect& dirtyRect, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin) final;
 
     struct PaintingState {
         PaintBehavior paintBehavior;
index a425f6b..b198a7c 100644 (file)
@@ -1166,7 +1166,7 @@ void ScrollView::paintPanScrollIcon(GraphicsContext& context)
     context.drawImage(*panScrollIcon, iconGCPoint);
 }
 
-void ScrollView::paint(GraphicsContext& context, const IntRect& rect)
+void ScrollView::paint(GraphicsContext& context, const IntRect& rect, SecurityOriginPaintPolicy securityOriginPaintPolicy)
 {
     if (platformWidget()) {
         Widget::paint(context, rect);
@@ -1198,7 +1198,7 @@ void ScrollView::paint(GraphicsContext& context, const IntRect& rect)
             context.clip(visibleContentRect(LegacyIOSDocumentVisibleRect));
         }
 
-        paintContents(context, documentDirtyRect);
+        paintContents(context, documentDirtyRect, securityOriginPaintPolicy);
     }
 
 #if ENABLE(RUBBER_BANDING)
index 2d3aef7..9622188 100644 (file)
@@ -344,7 +344,7 @@ public:
     }
 
     // Widget override. Handles painting of the contents of the view as well as the scrollbars.
-    WEBCORE_EXPORT void paint(GraphicsContext&, const IntRect&) final;
+    WEBCORE_EXPORT void paint(GraphicsContext&, const IntRect&, Widget::SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin) final;
     void paintScrollbars(GraphicsContext&, const IntRect&);
 
     // Widget overrides to ensure that our children's visibility status is kept up to date when we get shown and hidden.
@@ -380,7 +380,7 @@ protected:
     ScrollView();
 
     virtual void repaintContentRectangle(const IntRect&);
-    virtual void paintContents(GraphicsContext&, const IntRect& damageRect) = 0;
+    virtual void paintContents(GraphicsContext&, const IntRect& damageRect, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin) = 0;
 
     virtual void paintOverhangAreas(GraphicsContext&, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
 
index 5d0a8ef..050d4d9 100644 (file)
@@ -157,7 +157,7 @@ void Scrollbar::updateThumbProportion()
     updateThumb();
 }
 
-void Scrollbar::paint(GraphicsContext& context, const IntRect& damageRect)
+void Scrollbar::paint(GraphicsContext& context, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy)
 {
     if (context.updatingControlTints() && theme().supportsControlTints()) {
         invalidate();
index a236c7e..a3d7d9f 100644 (file)
@@ -85,7 +85,7 @@ public:
     WEBCORE_EXPORT void setProportion(int visibleSize, int totalSize);
     void setPressedPos(int p) { m_pressedPos = p; }
 
-    void paint(GraphicsContext&, const IntRect& damageRect) override;
+    void paint(GraphicsContext&, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin) override;
 
     bool enabled() const { return m_enabled; }
     virtual void setEnabled(bool);
index 55b49a4..47dce78 100644 (file)
@@ -114,7 +114,9 @@ public:
     void move(int x, int y) { setFrameRect(IntRect(x, y, width(), height())); }
     void move(const IntPoint& p) { setFrameRect(IntRect(p, size())); }
 
-    WEBCORE_EXPORT virtual void paint(GraphicsContext&, const IntRect&);
+    enum class SecurityOriginPaintPolicy { AnyOrigin, AccessibleOriginOnly };
+
+    WEBCORE_EXPORT virtual void paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin);
     void invalidate() { invalidateRect(boundsRect()); }
     virtual void invalidateRect(const IntRect&) = 0;
 
index 633696f..4caeb49 100644 (file)
@@ -103,6 +103,8 @@ public:
     virtual bool affectsOpacity() const { return false; }
     // True if the the value of one pixel can affect the value of another pixel under this operation, such as blur.
     virtual bool movesPixels() const { return false; }
+    // True if the filter should not be allowed to work on content that is not available from this security origin.
+    virtual bool shouldBeRestrictedBySecurityOrigin() const { return false; }
     // True if the filter needs the size of the box in order to calculate the animations.
     virtual bool blendingNeedsRendererSize() const { return false; }
 
@@ -182,6 +184,9 @@ public:
 
     bool affectsOpacity() const override { return true; }
     bool movesPixels() const override { return true; }
+    // FIXME: This only needs to return true for graphs that include ConvolveMatrix, DisplacementMap, Morphology and possibly Lighting.
+    // https://bugs.webkit.org/show_bug.cgi?id=171753
+    bool shouldBeRestrictedBySecurityOrigin() const override { return true; }
 
     const String& url() const { return m_url; }
     const String& fragment() const { return m_fragment; }
index dc2be1b..a1824f9 100644 (file)
@@ -137,6 +137,15 @@ bool FilterOperations::hasFilterThatMovesPixels() const
     return false;
 }
 
+bool FilterOperations::hasFilterThatShouldBeRestrictedBySecurityOrigin() const
+{
+    for (auto& operation : m_operations) {
+        if (operation->shouldBeRestrictedBySecurityOrigin())
+            return true;
+    }
+    return false;
+}
+
 TextStream& operator<<(TextStream& ts, const FilterOperations& filters)
 {
     for (size_t i = 0; i < filters.size(); ++i) {
index 486f686..0752e8d 100644 (file)
@@ -56,6 +56,7 @@ public:
 
     bool hasFilterThatAffectsOpacity() const;
     bool hasFilterThatMovesPixels() const;
+    bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const;
 
     bool hasReferenceFilter() const;
 
index ed30ab0..60f1bbc 100644 (file)
@@ -184,7 +184,7 @@ NSView *Widget::getOuterView() const
     return view;
 }
 
-void Widget::paint(GraphicsContext& p, const IntRect& r)
+void Widget::paint(GraphicsContext& p, const IntRect& r, SecurityOriginPaintPolicy)
 {
     if (p.paintingDisabled())
         return;
index f59f15f..4254ef9 100644 (file)
@@ -128,6 +128,7 @@ RefPtr<FilterEffect> FilterEffectRenderer::buildReferenceFilter(RenderElement& r
 bool FilterEffectRenderer::build(RenderElement& renderer, const FilterOperations& operations, FilterConsumer consumer)
 {
     m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
+    m_hasFilterThatShouldBeRestrictedBySecurityOrigin = operations.hasFilterThatShouldBeRestrictedBySecurityOrigin();
     if (m_hasFilterThatMovesPixels)
         m_outsets = operations.outsets();
 
index bc2386a..f8eab8f 100644 (file)
@@ -84,6 +84,7 @@ public:
     void apply();
 
     bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
+    bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; }
 
 private:
     FilterEffectRenderer();
@@ -115,6 +116,7 @@ private:
 
     bool m_graphicsBufferAttached { false };
     bool m_hasFilterThatMovesPixels { false };
+    bool m_hasFilterThatShouldBeRestrictedBySecurityOrigin { false };
 };
 
 inline FilterEffectRendererHelper::FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext)
index 84d46b6..5a6748e 100644 (file)
@@ -50,7 +50,8 @@ typedef HashMap<OverlapTestRequestClient*, IntRect> OverlapTestRequestMap;
 struct PaintInfo {
     PaintInfo(GraphicsContext& newContext, const LayoutRect& newRect, PaintPhase newPhase, PaintBehavior newPaintBehavior,
         RenderObject* newSubtreePaintRoot = nullptr, ListHashSet<RenderInline*>* newOutlineObjects = nullptr,
-        OverlapTestRequestMap* overlapTestRequests = nullptr, const RenderLayerModelObject* newPaintContainer = nullptr)
+        OverlapTestRequestMap* overlapTestRequests = nullptr, const RenderLayerModelObject* newPaintContainer = nullptr,
+        bool newRequireSecurityOriginAccessForWidgets = false)
             : rect(newRect)
             , phase(newPhase)
             , paintBehavior(newPaintBehavior)
@@ -58,6 +59,7 @@ struct PaintInfo {
             , outlineObjects(newOutlineObjects)
             , overlapTestRequests(overlapTestRequests)
             , paintContainer(newPaintContainer)
+            , requireSecurityOriginAccessForWidgets(newRequireSecurityOriginAccessForWidgets)
             , m_context(&newContext)
     {
     }
@@ -120,6 +122,7 @@ struct PaintInfo {
     ListHashSet<RenderInline*>* outlineObjects; // used to list outlines that should be painted by a block with inline children
     OverlapTestRequestMap* overlapTestRequests;
     const RenderLayerModelObject* paintContainer; // the layer object that originates the current painting
+    bool requireSecurityOriginAccessForWidgets { false };
 
 private:
     GraphicsContext* m_context;
index bb3d2b7..0238252 100644 (file)
@@ -3843,11 +3843,11 @@ bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularit
     return ScrollableArea::scroll(direction, granularity, multiplier);
 }
 
-void RenderLayer::paint(GraphicsContext& context, const LayoutRect& damageRect, const LayoutSize& subpixelOffset, PaintBehavior paintBehavior, RenderObject* subtreePaintRoot, PaintLayerFlags paintFlags)
+void RenderLayer::paint(GraphicsContext& context, const LayoutRect& damageRect, const LayoutSize& subpixelOffset, PaintBehavior paintBehavior, RenderObject* subtreePaintRoot, PaintLayerFlags paintFlags, SecurityOriginPaintPolicy paintPolicy)
 {
     OverlapTestRequestMap overlapTestRequests;
 
-    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, subpixelOffset, subtreePaintRoot, &overlapTestRequests);
+    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, subpixelOffset, subtreePaintRoot, &overlapTestRequests, paintPolicy == SecurityOriginPaintPolicy::AccessibleOriginOnly);
     paintLayer(context, paintingInfo, paintFlags);
 
     for (auto& widget : overlapTestRequests.keys())
@@ -4242,6 +4242,8 @@ std::unique_ptr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsCo
     // Note that we will still apply the clipping on the final rendering of the filter.
     paintingInfo.clipToDirtyRect = !filterInfo.renderer()->hasFilterThatMovesPixels();
 
+    paintingInfo.requireSecurityOriginAccessForWidgets = filterInfo.renderer()->hasFilterThatShouldBeRestrictedBySecurityOrigin();
+
     return WTFMove(painter.second);
 }
 
@@ -4809,7 +4811,7 @@ void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const L
         if (shouldClip)
             clipToRect(context, localPaintingInfo, fragment.foregroundRect);
     
-        PaintInfo paintInfo(context, fragment.foregroundRect.rect(), phase, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
+        PaintInfo paintInfo(context, fragment.foregroundRect.rect(), phase, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer(), localPaintingInfo.requireSecurityOriginAccessForWidgets);
         if (phase == PaintPhaseForeground)
             paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
         renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
index 6e17507..b9e5e3e 100644 (file)
@@ -496,12 +496,14 @@ public:
     
     typedef unsigned PaintLayerFlags;
 
+    enum class SecurityOriginPaintPolicy { AnyOrigin, AccessibleOriginOnly };
+
     // The two main functions that use the layer system.  The paint method
     // paints the layers that intersect the damage rect from back to
     // front.  The hitTest method looks for mouse events by walking
     // layers that intersect the point from front to back.
     void paint(GraphicsContext&, const LayoutRect& damageRect, const LayoutSize& subpixelOffset = LayoutSize(), PaintBehavior = PaintBehaviorNormal,
-        RenderObject* subtreePaintRoot = nullptr, PaintLayerFlags = 0);
+        RenderObject* subtreePaintRoot = nullptr, PaintLayerFlags = 0, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin);
     bool hitTest(const HitTestRequest&, HitTestResult&);
     bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&);
     void paintOverlayScrollbars(GraphicsContext&, const LayoutRect& damageRect, PaintBehavior, RenderObject* subtreePaintRoot = nullptr);
@@ -718,14 +720,14 @@ private:
     enum CollectLayersBehavior { StopAtStackingContexts, StopAtStackingContainers };
 
     struct LayerPaintingInfo {
-        LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect, PaintBehavior inPaintBehavior, const LayoutSize& inSupixelOffset, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr)
+        LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect, PaintBehavior inPaintBehavior, const LayoutSize& inSupixelOffset, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr, bool inRequireSecurityOriginAccessForWidgets = false)
             : rootLayer(inRootLayer)
             , subtreePaintRoot(inSubtreePaintRoot)
             , paintDirtyRect(inDirtyRect)
             , subpixelOffset(inSupixelOffset)
             , overlapTestRequests(inOverlapTestRequests)
             , paintBehavior(inPaintBehavior)
-            , clipToDirtyRect(true)
+            , requireSecurityOriginAccessForWidgets(inRequireSecurityOriginAccessForWidgets)
         { }
         RenderLayer* rootLayer;
         RenderObject* subtreePaintRoot; // only paint descendants of this object
@@ -733,7 +735,8 @@ private:
         LayoutSize subpixelOffset;
         OverlapTestRequestMap* overlapTestRequests; // May be null.
         PaintBehavior paintBehavior;
-        bool clipToDirtyRect;
+        bool requireSecurityOriginAccessForWidgets;
+        bool clipToDirtyRect { true };
     };
 
     // Compute, cache and return clip rects computed with the given layer as the root.
index c52a4ce..56bf759 100644 (file)
@@ -102,7 +102,7 @@ void RenderScrollbar::styleChanged()
     updateScrollbarParts();
 }
 
-void RenderScrollbar::paint(GraphicsContext& context, const IntRect& damageRect)
+void RenderScrollbar::paint(GraphicsContext& context, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy)
 {
     if (context.updatingControlTints()) {
         updateScrollbarParts();
index bdb81da..176fcca 100644 (file)
@@ -66,7 +66,7 @@ private:
     void setParent(ScrollView*) override;
     void setEnabled(bool) override;
 
-    void paint(GraphicsContext&, const IntRect& damageRect) override;
+    void paint(GraphicsContext&, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy) override;
 
     void setHoveredPart(ScrollbarPart) override;
     void setPressedPart(ScrollbarPart) override;
index 623a6c7..b5b1888 100644 (file)
@@ -31,6 +31,7 @@
 #include "RenderLayer.h"
 #include "RenderLayerBacking.h"
 #include "RenderView.h"
+#include "SecurityOrigin.h"
 #include <wtf/StackStats.h>
 #include <wtf/Ref.h>
 
@@ -216,6 +217,13 @@ void RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
 
 void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
+    if (paintInfo.requireSecurityOriginAccessForWidgets) {
+        if (auto contentDocument = frameOwnerElement().contentDocument()) {
+            if (!document().securityOrigin().canAccess(contentDocument->securityOrigin()))
+                return;
+        }
+    }
+
     IntPoint contentPaintOffset = roundedIntPoint(paintOffset + location() + contentBoxRect().location());
     // Tell the widget to paint now. This is the only time the widget is allowed
     // to paint itself. That way it will composite properly with z-indexed layers.
@@ -229,8 +237,8 @@ void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintO
         paintInfo.context().translate(widgetPaintOffset);
         paintRect.move(-widgetPaintOffset);
     }
-    // FIXME: Remove repaintrect encolsing/integral snapping when RenderWidget becomes device pixel snapped.
-    m_widget->paint(paintInfo.context(), snappedIntRect(paintRect));
+    // FIXME: Remove repaintrect enclosing/integral snapping when RenderWidget becomes device pixel snapped.
+    m_widget->paint(paintInfo.context(), snappedIntRect(paintRect), paintInfo.requireSecurityOriginAccessForWidgets ? Widget::SecurityOriginPaintPolicy::AccessibleOriginOnly : Widget::SecurityOriginPaintPolicy::AnyOrigin);
 
     if (!widgetPaintOffset.isZero())
         paintInfo.context().translate(-widgetPaintOffset);
index 99565b2..53ca6f6 100644 (file)
@@ -1,3 +1,17 @@
+2017-05-05  Dean Jackson  <dino@apple.com>
+
+        Restrict SVG filters to accessible security origins
+        https://bugs.webkit.org/show_bug.cgi?id=118689
+        <rdar://problem/27362159>
+
+        Reviewed by Brent Fulgham.
+
+        Update parameter lists.
+
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::paint):
+        * WebProcess/Plugins/PluginView.h:
+
 2017-05-05  Beth Dakin  <bdakin@apple.com>
 
         Ensure NSColorPickerTouchBarItem only uses sRGB colors
index 8c04351..45bdc19 100644 (file)
@@ -782,7 +782,7 @@ void PluginView::setFrameRect(const WebCore::IntRect& rect)
     viewGeometryDidChange();
 }
 
-void PluginView::paint(GraphicsContext& context, const IntRect& /*dirtyRect*/)
+void PluginView::paint(GraphicsContext& context, const IntRect& /*dirtyRect*/, Widget::SecurityOriginPaintPolicy)
 {
     if (!m_plugin || !m_isInitialized || m_pluginElement->displayState() < HTMLPlugInElement::Restarting)
         return;
index f7bcddc..d34748d 100644 (file)
@@ -171,7 +171,7 @@ private:
 
     // WebCore::Widget
     void setFrameRect(const WebCore::IntRect&) override;
-    void paint(WebCore::GraphicsContext&, const WebCore::IntRect&) override;
+    void paint(WebCore::GraphicsContext&, const WebCore::IntRect&, WebCore::Widget::SecurityOriginPaintPolicy) override;
     void invalidateRect(const WebCore::IntRect&) override;
     void setFocus(bool) override;
     void frameRectsChanged() override;