[...]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
In reply to Re: Piping to sendmail
by afoken
in thread Piping to sendmail
by Bod
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |