The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mail::Exim::Blacklist::Attachments - Reject email attachments

VERSION

version 2.000

SYNOPSIS

  acl_check_mime:

    warn
      condition = ${if and{{def:mime_filename} \
        {!match{${lc:$mime_filename}}{\N\.((json|xml)\.gz|zip)$\N}} \
        {eq{${perl{check_filename}{$mime_filename}}}{blocked}}}}
      set acl_m_blocked = yes

    warn
      condition = ${if match{${lc:$mime_filename}}{\N\. *(jar|zip)$\N}}
      decode = default
      condition = ${if eq{${perl{check_zip}{$mime_decoded_filename}}} \
                         {blocked}}
      set acl_m_blocked = yes

    accept

DESCRIPTION

A Perl module for the Exim mailer that checks email attachments for blocked filenames. Common executable, macro-enabled and archive file formats are rejected.

The list of blocked filename extensions is built from information published by Microsoft and Wikipedia.

SUBROUTINES/METHODS

check_filename

  my $result = check_filename($filename);

Checks if a filename has got a blocked extension. Returns "ok" or "blocked".

check_zip

  my $result = check_zip($input);

Checks a Zip archive for files with blocked filename extensions. Returns "ok" or "blocked".

DIAGNOSTICS

None.

CONFIGURATION AND ENVIRONMENT

Create a file such as /etc/exim/exim.pl. Add the following Perl code.

  use Mail::Exim::Blacklist::Attachments qw(check_filename check_zip);

Edit Exim's configuration file. Enable Perl and MIME part scanning in the main section.

  perl_startup = do '/etc/exim/exim.pl'
  perl_taintmode = yes

  acl_smtp_mime     = acl_check_mime
  acl_not_smtp_mime = acl_check_mime

Check for blocked filename extensions in the configuration file's ACL section, headed by begin acl.

  acl_check_mime:

    accept authenticated = *

    warn
      condition = ${if and{{def:mime_filename} \
        {!match{${lc:$mime_filename}}{\N\.((json|xml)\.gz|zip)$\N}} \
        {eq{${perl{check_filename}{$mime_filename}}}{blocked}}}}
      set acl_m_blocked = yes

    warn
      condition = ${if match{${lc:$mime_filename}}{\N\. *(jar|zip)$\N}}
      decode = default
      condition = ${if eq{${perl{check_zip}{$mime_decoded_filename}}} \
                         {blocked}}
      set acl_m_blocked = yes

    accept

Add statements that reject spam messages with blocked attachments to your DATA ACL.

  acl_check_data:

    deny message = Message rejected as high-probability spam
      spam = nobody:true
      condition = ${if >={$spam_score_int}{50}}

    deny message = Blocked attachment detected
      spam = nobody:true
      condition = ${if and{{>{$spam_score_int}{0}} \
                           {bool{$acl_m_blocked}}}}

    warn spam = nobody
      add_header = X-Spam-Flag: YES

    warn condition = ${if bool{$acl_m_blocked}}
      add_header = X-Warning: Blocked attachment detected

DEPENDENCIES

Requires the Perl modules Exporter and IO::Uncompress::Unzip, which are distributed with Perl.

INCOMPATIBILITIES

None.

AUTHOR

Andreas Vögele <voegelas@cpan.org>

BUGS AND LIMITATIONS

Legacy Microsoft Office filename extensions like .doc, .xls and .ppt are always considered to be macro-enabled. Scanning documents for macros is expensive and not worth the effort. Use .docx, .xlsx and .pptx instead.

The RAR decoder in popular file archivers and antivirus products has suffered from security vulnerabilities. I recommend to only accept Zip compressed data.

DMARC and SMTP TLS reporting send attachments with the filename extensions .json.gz and .xml.gz. Make sure that such messages are not rejected.

Headers that are added in Exim's MIME and DATA ACLs are not available to SpamAssassin. But you can pass ACL variables from the MIME to the DATA ACL.

LICENSE AND COPYRIGHT

Copyright 2021 Andreas Vögele

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.