<<< Date Index >>>     <<< Thread Index >>>

JavaMail allows directory traversal in attachments




1. INTRODUCTION

The JavaMail API provides a platform-independent and protocol-independent framework to build mail and messaging applications. The JavaMail API is implemented as a Java platform optional package and is also available as part of the Java 2 platform, Enterprise Edition.


2. SYNOPSIS

MimeBodyPart.getFileName () method in the JavaMail API doesn't properly validate filename attribute in Content-Disposition header, what makes it vulnerable to directory traversal attacks. Successful exploitation of this vulnerability allows writing arbitrary content in any directory accessible to the servlet running JavaMail.


3. AFFECTED VERSIONS

This vulnerability has been checked in current release, JavaMail 1.3.2. It may be present in all previous versions.


4. EXPLOITATION PROCEDURE

Send an email with the following filename attribute in Content-Disposition header:

../../../file.ext

This will write attachment three directories backward from expected location, as long as the servlet processing the email has writeable access to that directory.


5. EXAMPLE SCENARIO

This method uses getFileName () method to save the first attachment into a file:

protected void saveMailAttachment (javax.mail.internet.MimeMultipart mp) {
try {
int n = mp.getCount();
javax.mail.Part p = mp.getBodyPart (0);
String disposition = p.getDisposition ();

if (disposition != null &&
(disposition.equalsIgnoreCase (javax.mail.Part.ATTACHMENT)
|| disposition.equalsIgnoreCase (javax.mail.Part.INLINE) ) ) {

String filename = p.getFileName ();
File f = new File (filename);
OutputStream os = new BufferedOutputStream (new FileOutputStream (f) );
InputStream is = p.getInputStream ();
int c;
while ( (c = is.read () ) != -1)
os.write (c);
os.close ();
}
} catch (Exception e) { }
}


6. API DOCUMENTATION

getFileName

public java.lang.String getFileName() throws MessagingException

Get the filename associated with this part, if possible. Useful if this part represents an "attachment" that was loaded from a file. The filename will usually be a simple name, not including directory components.

Returns: Filename to associate with this part


7. VULNERABLE SOURCE CODE

The following code has been obtained by decompiling JavaMail MimeBodyPart class file. Although JavaMail source code is available from Sun’s site, checking this vulnerability over binaries is somewhat more reliable.

MimeBodyPart.java:

public String getFileName () throws MessagingException {
return getFileName ( ( (MimePart) (this) ) );
}

static String getFileName (MimePart mimepart) throws MessagingException {

String s = null;
String s1 = mimepart.getHeader ("Content-Disposition", null);

if (s1 != null) {
ContentDisposition contentdisposition = new ContentDisposition (s1);
s = contentdisposition.getParameter("filename");
}

if (s == null) {
String s2 = mimepart.getHeader ("Content-Type", null);
if (s2 != null)
try {
ContentType contenttype = new ContentType (s2);
s = contenttype.getParameter ("name");
} catch (ParseException _ex) { }
}

if (decodeFileName && s != null) {
try {
s = MimeUtility.decodeText(s);
} catch(UnsupportedEncodingException unsupportedencodingexception) {
throw new MessagingException
("Can't decode filename", unsupportedencodingexception);
}
}

return s;
}

Not that no check for directory traversal patterns is performed.


8. CURRENT WORKAROUND

Input validation mechanism should be enforced in the servlet being developed. No patches are available for this issue.


9. MORE INFORMATION

http://java.sun.com/products/javamail/

-------------------------------
Rafael San Miguel Carrasco
Security Consultant
rafael.sanmiguel@xxxxxx
+ 34 660 856 647
+ 34 902 464 546
Davinci Consulting - www.dvc.es
Oficina Madrid - Parque empresarial Alvento
Via de los Poblados 1 Edificio A 6ª planta
28033 Madrid
-------------------------------