Medium watch CVSS 4.3 chrome Info Disclosure 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactObservable discrepancy in SVG
DescriptionObservable discrepancy in SVG
ComponentSVG
Bug ClassInfo Disclosure
Action tierwatch — information disclosure — security-relevant, below the RCE-class bar
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker497854976
Fix commit0230e12ab236 (chromium/src) +98/-0
CWECWE-203
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N
CISA KEVNot listed
CreditedGoogle
Reported2026-03-30 (per vendor advisory)
Fix landed2026-07-24 (public git)
Disclosed2026-08-25
Patch gap32 days — fix public in source before the advisory

Background

Built-in filter inputs
SVG filter primitives can take the keywords SourceGraphic, SourceAlpha, FillPaint and StrokePaint as in/in2. SVGFilterBuilder turns them into effects in its builtin_effects_ map; FillPaint/StrokePaint are PaintFilterEffects built from the current fill/stroke flags.
Origin-tainted (`OriginTainted()` / `SetOriginTainted()`)
a flag on Blink FilterEffects saying the effect’s pixels come from cross-origin content. Effects whose geometry depends on input pixel values use it to switch off that behaviour.
`feDisplacementMap`
a primitive that moves in pixels by amounts read from the channels of in2. Per the new WPT tests, a tainted in2 should make the displacement “have no effect”, so cross-origin pixel values cannot control geometry.
Canvas `filter` with `url(#id)`
CanvasRenderingContext2D.filter can point to an SVG <filter>, so a page’s own canvas drawing (which may include cross-origin images or patterns) is fed through SVG filter primitives.

Root Cause Analysis

When svg_filter_builder.cc set up the built-in effects, it created SourceAlpha from SourceGraphic and FillPaint/StrokePaint as PaintFilterEffects from the current paint flags, but never copied SourceGraphic’s origin-tainted state onto them. So when the canvas SourceGraphic was tainted by cross-origin content, its alpha-derived sibling and the paint sources were reported as clean. Primitives that check taint, such as feDisplacementMap with in2="SourceAlpha", "FillPaint" or "StrokePaint", then used those cross-origin-derived pixels as displacement data. That broke the rule that every effect derived from tainted input is itself tainted.

The patch, placed right before AddBuiltinEffects(), loops over builtin_effects_ and calls SetOriginTainted() on each entry when source_graphic->OriginTainted() is true.

The patch comment admits this is a conservative assumption: it is exact for SourceAlpha and fits current FillPaint/StrokePaint users (<canvas>), where a cross-origin paint also taints SourceGraphic.

Key insight
Taint was set on SourceGraphic but not passed to the built-in inputs derived from it (SourceAlpha) or alongside it (FillPaint/StrokePaint), so taint-aware primitives treated cross-origin pixels as safe. The fix copies the SourceGraphic taint to every built-in effect.

Attack Path

  1. Load cross-origin image data into a canvas A web page draws a cross-origin image, or uses it as a createPattern() fill/stroke style, which taints the canvas SourceGraphic. Direct readback such as getImageData is still blocked by canvas origin-clean rules.
  2. Apply an SVG filter that reads a built-in input The page sets context.filter = 'url(#disp)', pointing to an feDisplacementMap whose in2 is SourceAlpha, FillPaint or StrokePaint, as in the shipped WPT tests.
  3. Displacement uses cross-origin pixels Before the fix, those inputs were not marked tainted, so the displacement was applied with offsets from cross-origin pixel values, where it should have had no effect.
  4. Observe the discrepancy The cross-origin content now shapes rendering in a way the page can observe outside the blocked readback path, for example through timing or other side channels on the filtered output (inferred; the patch shows only the missing taint, not a specific readout channel).

Impact Assessment

Ordinary web content, with no special flags or permissions, could make cross-origin image pixels drive geometric filter behaviour that the taint machinery is meant to suppress. This allows a renderer-side information leak of cross-origin image content, which the advisory calls “Observable discrepancy in SVG”. How much data can be recovered and by which observation channel is (inferred). The advisory gives no in-the-wild exploitation status.

Changed Functions

FunctionChangeNotes
for
third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
modified

Files Changed

  • third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
  • third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/reference/green-100x100.html
  • third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-fillpaint.sub.html
  • third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-strokepaint.sub.html
  • third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-sourcealpha.sub.html

Audit Directions

  • Taint propagation across derived effects
    Check every place that builds a FilterEffect from another effect or from paint flags (PaintFilterEffect, SourceAlpha, feImage, feTile, offscreen/paint-worklet sources) and confirm that OriginTainted() is propagated, not only set on the original source.
  • Consumers that branch on taint
    List the primitives that change behaviour on taint (feDisplacementMap and any lighting or convolution special cases) and check that they check every input (in and in2) after propagation, not only SourceGraphic.
  • Non-canvas paint sources
    The fix relies on FillPaint/StrokePaint taint matching SourceGraphic for <canvas>. Check CSS/SVG element filters, where paint servers such as cross-origin <pattern> images could be tainted while SourceGraphic is not.
From 0230e12ab23670f4004ee67f48896e8a68a7131e Mon Sep 17 00:00:00 2001
From: Fredrik Söderquist <fs@opera.com>
Date: Fri, 24 Jul 2026 03:49:43 -0700
Subject: [PATCH] Ensure FillPaint, StrokePaint and SourceAlpha sources are tainted

These sources would not get the tainted flag set if the canvas was
tainted.

Fixed: 497854976
Change-Id: If8217e5acfb0106b2b58a7234011ccfc39d7a83a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8121147
Reviewed-by: Philip Rogers <pdr@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/main@{#1667769}
---
diff --git a/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc b/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
index 30dd5f7..4a81812 100644
--- a/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
+++ b/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
@@ -122,6 +122,14 @@
                             MakeGarbageCollected<PaintFilterEffect>(
                                 source_graphic->GetFilter(), *stroke_flags));
   }
+  // If SourceGraphic is tainted, we assume that all other built-in effects are
+  // tainted as well. This is obviously true for SourceAlpha, and works out for
+  // all current users that pass values for {Fill,Stroke}Paint (i.e <canvas>).
+  if (source_graphic->OriginTainted()) {
+    for (auto& entry : builtin_effects_) {
+      entry.value->SetOriginTainted();
+    }
+  }
   AddBuiltinEffects();
 }
 
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/reference/green-100x100.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/reference/green-100x100.html
new file mode 100644
index 0000000..a3ab3bb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/reference/green-100x100.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-fillpaint.sub.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-fillpaint.sub.html
new file mode 100644
index 0000000..d614ef1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-fillpaint.sub.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>SVG &lt;feDisplacementMap> filter using a cross-origin FillPaint has no effect</title>
+<script src="/common/reftest-wait.js"></script>
+<link rel="match" href="reference/green-100x100.html">
+<canvas id="canvas" width="100" height="100">
+<svg width="0" height="0">
+  <filter id="disp">
+    <feDisplacementMap in="SourceGraphic" in2="FillPaint" scale="100"
+                       yChannelSelector="R" xChannelSelector="G"/>
+  </filter>
+</svg>
+<script>
+  const img = new Image();
+  img.onload = () => {
+    const context = canvas.getContext('2d');
+    context.fillStyle = 'red';
+    context.fillRect(0, 0, 100, 100);
+
+    context.fillStyle = context.createPattern(img, 'repeat');
+    context.strokeStyle = 'green';
+    context.lineWidth = 50;
+    context.filter = 'url(#disp)';
+    context.strokeRect(25, 25, 50, 50);
+
+    takeScreenshot();
+  };
+  img.onerror = takeScreenshot;
+  img.src = 'https://{{hosts[alt][www]}}:{{ports[https][0]}}/images/grgr-256x256.png';
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-sourcealpha.sub.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-sourcealpha.sub.html
new file mode 100644
index 0000000..46957b3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-sourcealpha.sub.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>SVG &lt;feDisplacementMap> filter using a tainted SourceAlpha has no effect</title>
+<script src="/common/reftest-wait.js"></script>
+<link rel="match" href="reference/green-100x100.html">
+<canvas id="canvas" width="100" height="100">
+<svg width="0" height="0">
+  <filter id="disp">
+    <feDisplacementMap in="SourceGraphic" in2="SourceAlpha" scale="100"
+                       yChannelSelector="A"/>
+  </filter>
+</svg>
+<script>
+  const img = new Image();
+  img.onload = () => {
+    const context = canvas.getContext('2d');
+    context.drawImage(img, 0, 0);
+    context.fillStyle = 'red';
+    context.fillRect(0, 0, 100, 100);
+
+    context.fillStyle = 'green';
+    context.filter = 'url(#disp)';
+    context.fillRect(0, 0, 100, 100);
+
+    takeScreenshot();
+  };
+  img.onerror = takeScreenshot;
+  img.src = 'https://{{hosts[alt][www]}}:{{ports[https][0]}}/images/grgr-256x256.png';
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-strokepaint.sub.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-strokepaint.sub.html
new file mode 100644
index 0000000..d2e7b0d4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-strokepaint.sub.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>SVG &lt;feDisplacementMap> filter using a cross-origin StrokePaint has no effect</title>
+<script src="/common/reftest-wait.js"></script>
+<link rel="match" href="reference/green-100x100.html">
+<canvas id="canvas" width="100" height="100">
+<svg width="0" height="0">
+  <filter id="disp">
+    <feDisplacementMap in="SourceGraphic" in2="StrokePaint" scale="100"
+                       yChannelSelector="R" xChannelSelector="G"/>
+  </filter>
+</svg>
+<script>
+  const img = new Image();
+  img.onload = () => {
+    const context = canvas.getContext('2d');
+    context.fillStyle = 'red';
+    context.fillRect(0, 0, 100, 100);
+
+    context.strokeStyle = context.createPattern(img, 'repeat');
+    context.fillStyle = 'green';
+    context.filter = 'url(#disp)';
+    context.fillRect(0, 0, 100, 100);
+
+    takeScreenshot();
+  };
+  img.onerror = takeScreenshot;
+  img.src = 'https://{{hosts[alt][www]}}:{{ports[https][0]}}/images/grgr-256x256.png';
+</script>
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/reference/green-100x100.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/reference/green-100x100.html
new file mode 100644
index 0000000..a3ab3bb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/reference/green-100x100.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-fillpaint.sub.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-fillpaint.sub.html
new file mode 100644
index 0000000..d614ef1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-fillpaint.sub.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>SVG &lt;feDisplacementMap> filter using a cross-origin FillPaint has no effect</title>
+<script src="/common/reftest-wait.js"></script>
+<link rel="match" href="reference/green-100x100.html">
+<canvas id="canvas" width="100" height="100">
+<svg width="0" height="0">
+  <filter id="disp">
+    <feDisplacementMap in="SourceGraphic" in2="FillPaint" scale="100"
+                       yChannelSelector="R" xChannelSelector="G"/>
+  </filter>
+</svg>
+<script>
+  const img = new Image();
+  img.onload = () => {
+    const context = canvas.getContext('2d');
+    context.fillStyle = 'red';
+    context.fillRect(0, 0, 100, 100);
+
+    context.fillStyle = context.createPattern(img, 'repeat');
+    context.strokeStyle = 'green';
+    context.lineWidth = 50;
+    context.filter = 'url(#disp)';
+    context.strokeRect(25, 25, 50, 50);
+
+    takeScreenshot();
+  };
+  img.onerror = takeScreenshot;
+  img.src = 'https://{{hosts[alt][www]}}:{{ports[https][0]}}/images/grgr-256x256.png';
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-sourcealpha.sub.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-sourcealpha.sub.html
new file mode 100644
index 0000000..46957b3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-sourcealpha.sub.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>SVG &lt;feDisplacementMap> filter using a tainted SourceAlpha has no effect</title>
+<script src="/common/reftest-wait.js"></script>
+<link rel="match" href="reference/green-100x100.html">
+<canvas id="canvas" width="100" height="100">
+<svg width="0" height="0">
+  <filter id="disp">
+    <feDisplacementMap in="SourceGraphic" in2="SourceAlpha" scale="100"
+                       yChannelSelector="A"/>
+  </filter>
+</svg>
+<script>
+  const img = new Image();
+  img.onload = () => {
+    const context = canvas.getContext('2d');
+    context.drawImage(img, 0, 0);
+    context.fillStyle = 'red';
+    context.fillRect(0, 0, 100, 100);
+
+    context.fillStyle = 'green';
+    context.filter = 'url(#disp)';
+    context.fillRect(0, 0, 100, 100);
+
+    takeScreenshot();
+  };
+  img.onerror = takeScreenshot;
+  img.src = 'https://{{hosts[alt][www]}}:{{ports[https][0]}}/images/grgr-256x256.png';
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-strokepaint.sub.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-strokepaint.sub.html
new file mode 100644
index 0000000..d2e7b0d4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/manual/filters/svg-displacement-filter-tainted-strokepaint.sub.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>SVG &lt;feDisplacementMap> filter using a cross-origin StrokePaint has no effect</title>
+<script src="/common/reftest-wait.js"></script>
+<link rel="match" href="reference/green-100x100.html">
+<canvas id="canvas" width="100" height="100">
+<svg width="0" height="0">
+  <filter id="disp">
+    <feDisplacementMap in="SourceGraphic" in2="StrokePaint" scale="100"
+                       yChannelSelector="R" xChannelSelector="G"/>
+  </filter>
+</svg>
+<script>
+  const img = new Image();
+  img.onload = () => {
+    const context = canvas.getContext('2d');
+    context.fillStyle = 'red';
+    context.fillRect(0, 0, 100, 100);
+
+    context.strokeStyle = context.createPattern(img, 'repeat');
+    context.fillStyle = 'green';
+    context.filter = 'url(#disp)';
+    context.fillRect(0, 0, 100, 100);
+
+    takeScreenshot();
+  };
+  img.onerror = takeScreenshot;
+  img.src = 'https://{{hosts[alt][www]}}:{{ports[https][0]}}/images/grgr-256x256.png';
+</script>
Loading diff…

Original Bug Report

reported by vm...@google.com

FeDisplacementMap timing side-channel bypass via untainted builtin SVG filter inputs

Project Fortify, an experimental security project, has identified the following potential security issue.

Overview: Blink’s SVG filter implementation potentially fails to propagate origin-taint status to builtin filter inputs like FillPaint, StrokePaint, and SourceAlpha. This oversight allows an attacker to bypass security restrictions on the <feDisplacementMap> filter intended to prevent timing side-channel attacks. By using a tainted canvas pattern as FillPaint for a displacement map, an attacker could extract cross-origin pixel data by measuring rendering time variations.

Affected files:

  • third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
  • third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc
  • third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
  • third_party/blink/renderer/core/paint/filter_effect_builder.cc
  • third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc
  • third_party/blink/renderer/platform/graphics/filters/source_alpha.cc

Estimated timestamp from git blame: 2020-02-18

Summary

A potential vulnerability in Blink’s SVG filter building logic allows an attacker to bypass the origin-taint check in the feDisplacementMap filter. This issue re-enables a timing side-channel attack where cross-origin pixel values can be extracted by observing variations in rendering performance, bypassing the defense originally implemented for crbug.com/778506.

Root Cause Analysis

The vulnerability stems from two related issues:

  1. Untainted Builtin Filter Effects: In SVGFilterBuilder::SVGFilterBuilder() (third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc), the builtin effects for FillPaint, StrokePaint, and SourceAlpha are created without propagating any origin-taint status:

    builtin_effects_.insert(FilterInputKeywords::SourceAlpha(),
                            MakeGarbageCollected<SourceAlpha>(source_graphic));
    if (fill_flags) {
      builtin_effects_.insert(FilterInputKeywords::FillPaint(),
                              MakeGarbageCollected<PaintFilterEffect>(
                                  source_graphic->GetFilter(), *fill_flags));
    }
    

    The FilterEffect base class defaults origin_tainted_ to false. While the canvas context may be tainted (e.g., by setting fillStyle to a cross-origin CanvasPattern), and SourceGraphic is correctly marked as tainted, the newly created PaintFilterEffect objects for FillPaint and StrokePaint are never explicitly marked as tainted. Consequently, their OriginTainted() methods incorrectly return false.

  2. Incomplete Security Check in FEDisplacementMap: The Filter Effects Module Level 1 specification requires feDisplacementMap to act as a pass-through filter if either the first or second input is origin-tainted to prevent timing attacks. However, in FEDisplacementMap::CreateImageFilter() (third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc), the implementation only checks the second input:

      // FEDisplacementMap must be a pass-through filter if
      // the origin is tainted. See:
      // https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions.
      if (InputEffect(1)->OriginTainted())
        return color;
    

    It misses the check for InputEffect(0)->OriginTainted().

Exploitation Scenario

If an attacker sets canvas.fillStyle to a cross-origin CanvasPattern and applies an SVG filter containing an <feDisplacementMap> element with in2="FillPaint", the cross-origin shader is carried into the FillPaint effect. Because FillPaint is incorrectly considered untainted, the security check in FEDisplacementMap is bypassed. The filter proceeds to use cross-origin pixel values as displacement vectors.

An attacker can perform a pixel-by-pixel extraction of cross-origin image content by measuring the time it takes to render a canvas with the displacement filter applied. Rendering timing varies depending on the displacement distance (driven by the victim pixel values), allowing for an information leak of cross-origin data (CWE-200).

Potential Reproduction Steps

Note: These are suggested steps to trigger the vulnerability. Tooling does not currently allow running arbitrary code to confirm the exploit.

  1. Host an attacker-controlled page with an inline SVG filter:
    <svg>
      <filter id="f">
        <feDisplacementMap in="SourceGraphic" in2="FillPaint" xChannelSelector="R" yChannelSelector="G" scale="500"/>
      </filter>
    </svg>
    
  2. Load a cross-origin image without CORS: img.src = 'https://victim.example/secret.png';
  3. Upon image load, create a pattern and set it as the canvas fillStyle (this taints the canvas context):
    const ctx = canvas.getContext('2d');
    const p = ctx.createPattern(img, 'repeat');
    ctx.fillStyle = p;
    ctx.filter = 'url(#f)';
    
  4. Repeatedly call ctx.fillRect(0,0,1,1) while varying SourceGraphic probe patterns and measuring execution time using performance.now().
  5. The render timing will depend on the R/G channel values of the cross-origin image at the displacement point. An attacker can binary-search for specific pixel values based on these timing variations.

Suggested Fix

  1. Propagate Taint Status to Builtin Effects: Update the SVGFilterBuilder constructor to mark the SourceAlpha, FillPaint, and StrokePaint effects as tainted if the incoming source_graphic is tainted or if the context flags contain cross-origin data. Alternatively, ensure the PaintFilterEffect itself evaluates taint based on the provided flags.
  2. Enforce Complete Security Check: Correct the implementation in FEDisplacementMap::CreateImageFilter() to check both inputs as required by the specification:
    if (InputEffect(0)->OriginTainted() || InputEffect(1)->OriginTainted())
      return color;
    

Evaluated with Chrome root at commit: a9cbf6e8b275fe4147435aa905f3b7f5a656f5f0


Results from so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker