Chrome · SVG
CVE-2026-11182
Logic Error in SVG
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
testthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.html |
modified | |
functionthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.html |
modified | |
testthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.html |
modified | |
functionthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.html |
modified | |
testthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.html |
modified | |
functionthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.html |
modified |
Files Changed
third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.ccthird_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.ccthird_party/blink/renderer/core/svg/svg_fe_flood_element.ccthird_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.ccthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.htmlthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.htmlthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.htmlthird_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_specular_filter_visited_color_taints.html
Patch
From dc628cfca1c243f174d45d7149d9c0b25e7168e0 Mon Sep 17 00:00:00 2001
From: Stephen Chenney <schenney@chromium.org>
Date: Mon, 04 May 2026 08:49:27 -0700
Subject: [PATCH] Improve tainting of SVG filters using colors
SVG filters that use colors as input should taint if
the color is `currentColor` because that may reference
visited link colors. The existing code was not accounting
for color functions that themselves used `currentColor`.
Also verified that system colors used in SVG filters on
canvas use the default system colors, not those from the
user's theme.
Bug: 502651014
Change-Id: I5df1a8ef30013ef6f5e1ced97aa88c0cf6bc9d4d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7808312
Reviewed-by: Fredrik Söderquist <fs@opera.com>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1624706}
---
diff --git a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
index 534ed73..77cf77d 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
@@ -155,7 +155,7 @@
// TaintsOrigin() is only called after a successful call to Build()
// (see above), so we should have a ComputedStyle here.
DCHECK(style);
- return style->LightingColor().IsCurrentColor();
+ return style->LightingColor().DependsOnCurrentColor();
}
SVGAnimatedPropertyBase* SVGFEDiffuseLightingElement::PropertyFromAttribute(
diff --git a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
index 9d72c0c4..fdd225e 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
@@ -128,7 +128,7 @@
// TaintsOrigin() is only called after a successful call to Build()
// (see above), so we should have a ComputedStyle here.
DCHECK(style);
- return style->FloodColor().IsCurrentColor();
+ return style->FloodColor().DependsOnCurrentColor();
}
SVGAnimatedPropertyBase* SVGFEDropShadowElement::PropertyFromAttribute(
diff --git a/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc b/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
index 95f73de..c8b8adf1 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
@@ -72,7 +72,7 @@
// TaintsOrigin() is only called after a successful call to Build()
// (see above), so we should have a ComputedStyle here.
DCHECK(style);
- return style->FloodColor().IsCurrentColor();
+ return style->FloodColor().DependsOnCurrentColor();
}
} // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
index 2bd2f7a7..37d490d2 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
@@ -168,7 +168,7 @@
// TaintsOrigin() is only called after a successful call to Build()
// (see above), so we should have a ComputedStyle here.
DCHECK(style);
- return style->LightingColor().IsCurrentColor();
+ return style->LightingColor().DependsOnCurrentColor();
}
SVGAnimatedPropertyBase* SVGFESpecularLightingElement::PropertyFromAttribute(
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.html
new file mode 100644
index 0000000..338f896
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>SVG diffuse lighting filter using visited link color should taint the canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ a {
+ color: green;
+ }
+ a:visited {
+ color: red;
+ }
+</style>
+<a id="L_visited" href="">
+ <svg width="100" height="100">
+ <filter id="F_visited">
+ <feDiffuseLighting lighting-color="color-mix(in srgb, currentColor 99%, transparent)">
+ <fePointLight x="150" y="60" z="20" />
+ </feDiffuseLighting>
+ </filter>
+ </svg>
+</a>
+<canvas id=canvas width=100 height=100>
+<script>
+test(function() {
+ context = canvas.getContext("2d");
+ context.filter = "url(#F_visited)";
+ context.fillRect(0, 0, 100, 100);
+
+ // The canvas should be tainted, so the following should throw.
+ assert_throws_dom("SecurityError",
+ function () { canvas.toDataURL() },
+ 'canvas.toDataURL should throw SecurityError for SVG using visited color.'
+ );
+}, "Tainting check for visited link in SVG diffuse lighting filter");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.html
new file mode 100644
index 0000000..608e63e0a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>SVG drop shadow filter using visited link color should taint the canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ a {
+ color: green;
+ }
+ a:visited {
+ color: red;
+ }
+</style>
+<a id="L_visited" href="">
+ <svg width="100" height="100">
+ <filter id="F_visited">
+ <feDropShadow dx="0" dy="0" stdDeviation="0.5" flood-color="color-mix(in srgb, currentColor 99%, transparent)" />
+ </filter>
+ </svg>
+</a>
+<canvas id=canvas width=100 height=100>
+<script>
+test(function() {
+ context = canvas.getContext("2d");
+ context.filter = "url(#F_visited)";
+ context.fillRect(0, 0, 100, 100);
+
+ // The canvas should be tainted, so the following should throw.
+ assert_throws_dom("SecurityError",
+ function () { canvas.toDataURL() },
+ 'canvas.toDataURL should throw SecurityError for SVG using visited color.'
+ );
+}, "Tainting check for visited link in SVG drop shadowfilter");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.html
new file mode 100644
index 0000000..7c0a6a3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>SVG flood filter using visited link color should taint the canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ a {
+ color: green;
+ }
+ a:visited {
+ color: red;
+ }
+</style>
+<a id="L_visited" href="">
+ <svg width="100" height="100">
+ <filter id="F_visited">
+ <feFlood flood-color="color-mix(in srgb, currentColor 99%, transparent)"/>
+ </filter>
+ </svg>
+</a>
+<canvas id=canvas width=100 height=100>
+<script>
+test(function() {
+ context = canvas.getContext("2d");
+ context.filter = "url(#F_visited)";
+ context.fillRect(0, 0, 100, 100);
+
+ // The canvas should be tainted, so the following should throw.
+ assert_throws_dom("SecurityError",
+ function () { canvas.toDataURL() },
+ 'canvas.toDataURL should throw SecurityError for SVG using visited color.'
+ );
+}, "Tainting check for visited link in SVG flood filter");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_specular_filter_visited_color_taints.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_specular_filter_visited_color_taints.html
new file mode 100644
index 0000000..83d11ce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_specular_filter_visited_color_taints.html
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.html
new file mode 100644
index 0000000..338f896
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_diffuse_filter_visited_color_taints.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>SVG diffuse lighting filter using visited link color should taint the canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ a {
+ color: green;
+ }
+ a:visited {
+ color: red;
+ }
+</style>
+<a id="L_visited" href="">
+ <svg width="100" height="100">
+ <filter id="F_visited">
+ <feDiffuseLighting lighting-color="color-mix(in srgb, currentColor 99%, transparent)">
+ <fePointLight x="150" y="60" z="20" />
+ </feDiffuseLighting>
+ </filter>
+ </svg>
+</a>
+<canvas id=canvas width=100 height=100>
+<script>
+test(function() {
+ context = canvas.getContext("2d");
+ context.filter = "url(#F_visited)";
+ context.fillRect(0, 0, 100, 100);
+
+ // The canvas should be tainted, so the following should throw.
+ assert_throws_dom("SecurityError",
+ function () { canvas.toDataURL() },
+ 'canvas.toDataURL should throw SecurityError for SVG using visited color.'
+ );
+}, "Tainting check for visited link in SVG diffuse lighting filter");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.html
new file mode 100644
index 0000000..608e63e0a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_drop_shadow_filter_visited_color_taints.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>SVG drop shadow filter using visited link color should taint the canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ a {
+ color: green;
+ }
+ a:visited {
+ color: red;
+ }
+</style>
+<a id="L_visited" href="">
+ <svg width="100" height="100">
+ <filter id="F_visited">
+ <feDropShadow dx="0" dy="0" stdDeviation="0.5" flood-color="color-mix(in srgb, currentColor 99%, transparent)" />
+ </filter>
+ </svg>
+</a>
+<canvas id=canvas width=100 height=100>
+<script>
+test(function() {
+ context = canvas.getContext("2d");
+ context.filter = "url(#F_visited)";
+ context.fillRect(0, 0, 100, 100);
+
+ // The canvas should be tainted, so the following should throw.
+ assert_throws_dom("SecurityError",
+ function () { canvas.toDataURL() },
+ 'canvas.toDataURL should throw SecurityError for SVG using visited color.'
+ );
+}, "Tainting check for visited link in SVG drop shadowfilter");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.html
new file mode 100644
index 0000000..7c0a6a3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_flood_filter_visited_color_taints.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>SVG flood filter using visited link color should taint the canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ a {
+ color: green;
+ }
+ a:visited {
+ color: red;
+ }
+</style>
+<a id="L_visited" href="">
+ <svg width="100" height="100">
+ <filter id="F_visited">
+ <feFlood flood-color="color-mix(in srgb, currentColor 99%, transparent)"/>
+ </filter>
+ </svg>
+</a>
+<canvas id=canvas width=100 height=100>
+<script>
+test(function() {
+ context = canvas.getContext("2d");
+ context.filter = "url(#F_visited)";
+ context.fillRect(0, 0, 100, 100);
+
+ // The canvas should be tainted, so the following should throw.
+ assert_throws_dom("SecurityError",
+ function () { canvas.toDataURL() },
+ 'canvas.toDataURL should throw SecurityError for SVG using visited color.'
+ );
+}, "Tainting check for visited link in SVG flood filter");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_specular_filter_visited_color_taints.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_specular_filter_visited_color_taints.html
new file mode 100644
index 0000000..83d11ce
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg_specular_filter_visited_color_taints.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>SVG specular lighting filter using visited link color should taint the canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ a {
+ color: green;
+ }
+ a:visited {
+ color: red;
+ }
+</style>
+<a id="L_visited" href="">
+ <svg width="100" height="100">
+ <filter id="F_visited">
+ <feSpecularLighting specularExponent="20" lighting-color="color-mix(in srgb, currentColor 99%, transparent)">
+ <fePointLight x="150" y="60" z="20" />
+ </feDiffuseLighting>
+ </filter>
+ </svg>
+</a>
+<canvas id=canvas width=100 height=100>
+<script>
+test(function() {
+ context = canvas.getContext("2d");
+ context.filter = "url(#F_visited)";
+ context.fillRect(0, 0, 100, 100);
+
+ // The canvas should be tainted, so the following should throw.
+ assert_throws_dom("SecurityError",
+ function () { canvas.toDataURL() },
+ 'canvas.toDataURL should throw SecurityError for SVG using visited color.'
+ );
+}, "Tainting check for visited link in SVG specular lighting filter");
+</script>
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page