Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Perl script for body rewrite

by fgarpe (Initiate)
on Sep 11, 2020 at 11:55 UTC ( #11121610=perlquestion: print w/replies, xml ) Need Help??

fgarpe has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
this is my first post in this site and I'm a new user... also i don't have much knowledge of perl :(, sorry. I know that perl it's a great language with which you can do fantastic things, but my work has taken me in other directions. Now my question.

I want to add a warning message like this:

CYBER SECURITY WARNING: This email is from an external source - be careful of attachments and links

In top of all incoming emails that come from external sources using exim, the best option that I can see is write a script thats is calling during transport, this script can read the entire mail and can do some modifications to it. In the exim docs are an example writed in perl, and seems like this is the best option to do this. Using this script as base I have done this:

please don't laugh too much :D

#!/usr/bin/perl $/ = ""; # set paragraph mode chomp($headers = <STDIN>); # read a paragraph, remove trailing newlin +es $/ = "\n"; # unset paragraph mode printf(STDOUT "%s\n\n", $headers); while (<STDIN>) { if ($_ eq "Content-Type: text/plain; charset=utf-8\n"){ $p = 'y'; } if ($_ eq "Content-Type: text/html; charset=utf-8\n"){ $y = 'y'; } printf(STDOUT "%s\n", $_); if ( $p eq 'y'){ printf (STDOUT "%s\n", "WARNING IN PLAIN TEXT") ; $p = 'n'; } if ( $y eq 'y'){ printf (STDOUT "%s\n", 'HTML WARNING') ; $y = 'n'; } }

with the first tests everything seemed to work well, but when I tested it with real emails I had received the bugs began to appear. According to the MIME standard there are a lot of headers that can appear in the mail body (Content-Type, Content-Disposition, Content-Transfer-Encoding, etc), see the following link for more info:

I don't have always the same headers, sometimes they appear just above de body, others there are others headers before the body, depends on the origin server, some examples at bottom. I'm desperate and frustrated.

Can someone help me to extract only the part of the message, either in html, in plain text or coded in base64 so I can add the warning?

Thank you very much

------------------------------- SOME EXAMPLES -------------------------------

Example 1:
MIME-Version: 1.0
Content-type: text/html; charset=iso-8859-1
From: ******** <*******@**********>
Message-Id: <20200910203400.8DD062046864@********>
Date: Thu, 10 Sep 2020 22:34:00 +0200 (CEST)
... more headers ...
the html message

Example 2:
x-ms-exchange-transport-crosstenantheadersstamped: DB6PR0501MB2792
Content-Type: multipart/related;
MIME-Version: 1.0
... more headers ...
Content-Type: multipart/alternative;

Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64

the message in plain text encoded in base64

Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64

the message in html encoded in base64

Example 3:
MIME-Version: 1.0
Content-Type: multipart/mixed;
Thread-Topic: *************************************************************
Thread-Index: AdaFB4a1gtdC+dbyQ2GK8Qrlu/b37EPAIenT

Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

the message in plain text

Content-Type: application/pdf;
Content-Disposition: attachment;
Content-Transfer-Encoding: base64

Replies are listed 'Best First'.
Re: Perl script for body rewrite
by Perlbotics (Bishop) on Sep 11, 2020 at 17:59 UTC

    I do not want to discourage your attempt but our company uses the same BS with the result, that it is typically ignored - like those flickering ADs one learns to ignore after some time.

    So pardon me for sounding sunny, but there are a few more things to consider. Your matches are too specific. They seem to fit just for the few examples you've provided. When you going down this path, use loads of test automation. What you need is a parser that splits the email into its components, detecting header and body for each component (header and body are separated by at least one empty line - your matches might trigger within a header and corrupt the whole thing). You already handling text and HTML formats, however, producing valid HTML would need you to inject your message somewhere after the <body> tag. Take additonal care not to mess up encrypted or signed parts of the mail. There might be a suitable library in the MIME:: section of CPAN that could support you more reliably. Perhaps MIME::Fast or MIME::Tools?

      Take additonal care not to mess up encrypted or signed parts of the mail.

      This. You (fgarpe) are onto a hiding to nothing.

      I also agree with Perlbotics in that your users will become warning-blind and rapidly ignore it. If you absolutely must do this because the legals have insisted then I humbly suggest that you alter the Subject line only. Much simpler, no MIME involved, you just need to get the encoding right.

      Good luck.


Re: Perl script for body rewrite
by jcb (Vicar) on Sep 11, 2020 at 22:14 UTC

    I second the concern other monks have raised: if you use secured emails (signed and/or encrypted) in your environment, you will need to be VERY careful not to break those messages. Altering only the Subject header is much safer, and I recommend only appending a parenthetical "(EXTERNAL ORIGIN)" there.

    You could also (probably) alter the display name in the From header to insert "(EXTERNAL ORIGIN)" similarly, but see the other monks' concerns that users will learn to ignore the warning.

    If you are really this paranoid, the best solution is to set up a parallel internal-only email system such that each user will have two inboxes: one that receives mail globally and one that only receives internal mail. Most modern clients can easily handle multiple accounts.

Re: Perl script for body rewrite
by fgarpe (Initiate) on Sep 11, 2020 at 22:58 UTC

    thank you very much, especially to Perlbotics for his suggestions on mime::tools, I'm going to play with that library for a while.

    I agree that many users will end up ignoring the message, sad but true. We use anti-spam and anti-phishing systems that block most malicious emails, but there is no system that is 100% effective. We carry out regular awareness campaigns, when we detect a phishing email we warn all users who have received it that it is a malicious message, we send fake phishing messages and we force people who are deceived to take a training course... even so, there are users who continue to fall into the trap. I think this is about putting layers that increase security, in this case on the weakest link in the chain, the users. This is another layer, nothing more, it may not be especially effective, but if I can get at least one user not to fall into the trap in each attack, it will have been worth it. When this one is working I'll put another, and then another and another. This is part of my job.

    Again, thank you very much, any other suggestions are welcome

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11121610]
Approved by marto
Front-paged by haukex
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2020-09-20 08:22 GMT
Find Nodes?
    Voting Booth?
    If at first I donít succeed, I Ö

    Results (120 votes). Check out past polls.