MIME::Tools is a very nice Perl module for parsing and constructing MIME-encoded mail messages. The latest stable version is 5.411a.
MIME::Tools works very well on valid MIME messages. However, there are a number of problems if you use it to implement server-based mail scanning.
Problem 1: RFC 2231 encoding not supported. http://www.ietf.org/rfc/rfc2231.txt specifies (yet another) way to encode filenames in MIME messages. MIME::Tools will not correctly recognize this attachment as "foo.exe":
Content-Disposition: attachment; filename1="foo."; filename2="exe"
Problem 2: Rejection of "obvious" interpretation of malformed MIME. The following MIME header is valid:
Content-Type: application/octet-stream; name="bad boy.exe"
But this header is not:
Content-Type: application/octet-stream; name=bad boy.exe
MIME::Tools interprets the name field as "bad" in this case, and throws away the " boy.exe" part. Unfortunately, most Windoze mail clients make the "obvious" interpretation and recognize the name as "bad boy.exe"
Problem 3: Incorrect concatenation of encoded MIME words. MIME::Tools does not remove the space from this example:
to yield (ab); instead, it yields "(a b)" Some MUA's use encoded MIME words in the Content-Type or Content-Disposition fields. Although this is specifically disallowed by RFC 2047, again, some Windoze mail clients may make the "obvious" interpretation and decode the words.
Problems 1 and 3 are real deficiencies in MIME::Tools. Problem 2 is not a deficiency in MIME::Tools itself, but that's cold comfort if a virus slips through your server-based scanner.
A patch which corrects problems 1-3 and does not break any MIME::Tools regression tests is at http://www.roaringpenguin.com/mimedefang/mime-tools-patch.txt
I make no guarantee that the above patch will catch all forms of malformed MIME which could be interpreted differently by an MUA. In fact, I'm willing to bet there are lots of ways to evade server-based scanners using MIME::Tools or practically any other MIME scanner.
If you use MIMEDefang (which uses MIME::Tools), you may want to unconditionally call action_rebuild in filter_begin(). This forces the MIME message to be rebuilt by MIME::Tools, resulting in a valid MIME message. This should guarantee that the MUA interprets the message exactly as MIME::Tools did, but it may introduce unacceptable processing overhead.
email@example.com contacted 30 May; no response yet.
-- David F. Skoll