open(MAIL,"|$send_path -t"); # send email headers print MAIL ("To: $send_addr\n"); print MAIL ("From: $from_addr\n"); print MAIL ("Subject: Lane Entry Form submitted\n\n"); # send email body print MAIL ("----- Notification of new Lane Data -----\n\n"); close(MAIL);
[...]

But it got me thinking that piping to sendmail is quite simple. The code is clear and, presumably, it is quite an efficient way to send an email.

Other than it not being portable away from an *nix environment, is there any reason not to do this?

If you do it as shown, you may be vulnerable to shell injection (via $send_path) AND header injection (via $send_addr and via $from_addr). If you insist on piping to sendmail, better use the multi-argument version of open, and pass sendmail and its arguments as a list instead of everything as a string. See The problem of "the" default shell for a longer discussion of the problem.

Apart from that, the "real" sendmail is a huge beast that does everything mail related, runs setuid, and has a very long history of serious security problems. If you are lucky, that does not affect your code, but sendmail itself is a bad idea. Several other mail solutions come with a sendmail binary that is just a bare minimum interface to the real mail solution.

No matter which sendmail you end up invoking, you need to run at least one external program, in case of a "fake" sendmail, that probably invokes another program to accept mails. That is usually not a big deal, but it needs more resources. Also, running an external program may fail. Finding out why might cause some trouble.

Sendmail's behaviour has changed over the years, and the "fake" sendmails may not be 100% compatible. Also, while sendmail once was almost universally available, these times are long gone, and that's a good thing. Your program may fail simply because there is no sendmail binary installed, or because it does not like the way you invoke it. Oh, and forget trying to pipe to sendmail on non-Unix systems; sendmail is a Unix thing.

SMTP, on the other hand, is a standard. It was extended several times, to add authentication and encryption, but all you need is TCP/IP networking and an SMTP server willing to accept mails. MIME::Lite is not recommended for new code, as it has some flaws, but for some cases (local network, single recipient), it is still good enough. CPAN has lots of other mail related modules, and you should use them. SMTP is implemented, you don't need to reinvent it. Creating messages, including attachments, is implemented, you don't need to reinvent it. Hopefully, the implementations you choose validate their arguments and ensure that no injection is possible.

Apart from mail-related things, consider enabling taint mode when processing input from the network ("form submitted" sounds like running from a webserver). Don't blindly untaint data, make sure data from the network has the expected format. If not, throw an error, don't try to recover. That works also without taint mode, but taint mode will cause a runtime error if you forget to check your input.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to Re: Piping to sendmail by afoken
in thread Piping to sendmail by Bod

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.