NAME

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

VERSION

version 1.006

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 identified.

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

Exim

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

use Mail::Exim::ACL::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.

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.

AUTHOR

Andreas Vögele <voegelas@cpan.org>

LICENSE AND COPYRIGHT

Copyright (C) 2024 Andreas Vögele

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