Stored-XSS via animate tag in Roundcube (CVE-2025-68461)
Stored-XSS via animate tag in Roundcube (CVE-2025-68461)
Description and Impact
| Type | Version Affected | Authentication Required | ?-day | CVSS |
|---|---|---|---|---|
| Stored-XSS | <1.5.12, <1.6.12 | Yes | 1-day | 7.2 |
Roundcube Webmail before 1.5.12 and 1.6 before 1.6.12 is prone to a Cross-Site-Scripting (XSS) vulnerability via the animate tag in an SVG document.
Root cause analysis
program\lib\Roundcube\rcube_washtml.php:dumpHtml()

Ứng dụng kiểm tra xem thẻ hiện tại ($tagName) có phải là một trong các thẻ hoạt ảnh (animate, animatecolor, …) hay không. Nếu đúng, nó gọi tiếp hàm self::attribute_value để kiểm tra xem thẻ này có chứa thuộc tính tên là attributename và giá trị của nó có đang được đặt là href hay không. Nếu cả 2 điều kiện đúng, nó sẽ chặn thẻ này.

Hàm attribute_value đi tìm trong thẻ đó xem có thuộc tính nào khớp tên ($attr_name) và khớp giá trị ($attr_value) hay không. Ở đây là nó so sánh chuỗi chính xác (chỉ bỏ qua chữ hoa/chữ thường và khoảng trắng thừa).
Bypass bằng cách thay href bằng xlink:href: <animate attributeName="xlink:href" ...> khi đó:
- Biến
$attr_valuemà hàm ở Ảnh 1 đang tìm kiếm là chuỗi'href'. - Nhưng giá trị thực tế truyền vào là chuỗi
xlink:href. - Khi hàm
attribute_value()thực hiện so sánh:'href' === 'xlink:href', kết quả trả về là False.
→ Ứng dũng sẽ bỏ qua if và không bị block.
Limitation
Để hiển thị email đồng nhất, ứng dụng bọc nội dung vào một cấu trúc HTML. Điều này ép lớp DOMDocument của PHP phải sử dụng trình phân tích cú pháp HTML (loadHTML()) thay vì XML (loadXML())



Trình phân tích HTML không hỗ trợ các tiêu chuẩn của XML namespace. Do đó, trong quá trình xử lý, nó đã âm thầm loại bỏ khai báo bắt buộc xmlns:xlink và tự động chuyển không gian tên của SVG (http://www.w3.org/2000/svg) sang chuẩn HTML (http://www.w3.org/1999/xhtml).
Từ phiên bản 1.5.8, Roundcube đã thêm CSP header khi người dùng xem ảnh trực tiếp trên trình duyệt:

Steps to Reproduce
Gửi mail kèm file svg với nội dung như sau:
xss.svg
<svg xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg">
<a>
<animate attributeName="xlink:href" dur="0.1s" fill="freeze"
values="javascript:alert(1)"/>
<text x="100" y="100"
font-weight="bold">Click me!!!</text>
</a>
</svg>

Open image in new tab:

Click → XSS:

Patch

Hàm Regex này sẽ tìm và xóa mọi thứ từ đầu chuỗi cho đến dấu hai chấm :.
Nếu truyền vào giá trị xlink:href (hoặc bất kỳ tên ảo nào như abc:href), hàm này sẽ cắt bỏ phần đầu, chỉ giữ lại chữ href.
Khi đó, phép so sánh cuối cùng sẽ là 'href' === 'href' (trả về True).