[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#47709: Some scripts way, way out of date



On Sun, 24 Oct 1999, Raul Miller wrote:

> What is the advantage of introducing a complex syntax which is not
> robust?

In my opinion, using Net::SMTP as I outlined is at least as robust as
invoking Sendmail directly, and provides several improvements.

1. There is no need to have any mail system whatsoever on the web server.

2. If there is a mail system on the web server, it can be any flavor of
SMTP daemon and need not be Sendmail.

3. The CGI program written in Perl is not tied to any specific web server,
Linux distribution, or Unix vendor, and would even work on Windows NT.

> Here's an excerpt from a cgi script of mine where I elected to use
> sendmail:
> 
> 	open MAIL, "|/usr/lib/sendmail -oi -oem -t"
> 		or die_cgi 503, "Can't send mail\n";
> 	print MAIL <<___ or die_cgi 503, "Can't compose email\n";
> To: $first_name $last_name <$email_address>
> From: ...
> Subject: ...
> Hi $first_name,

In order for this to work, the web server machine must have Sendmail
installed and configured.  There are a lot of legitimate reasons,
including complexity and security, why someone might regard this as
undesirable.  By default, I believe that Debian usually installs Smail
rather than Sendmail, although I am not sure (both packages are "extra")
since I always use Sendmail personally.  There are also several mail
servers, including smtpd, which cannot be invoked directly from the
console but can be used over an SMTP connection with Net::SMTP.

> Naturally, all the shell variables come from a cgi script, and naturally
> any would have been rejected if they contained problematic characters.
> Now what you're saying is that I should replace this rather trivial perl
> fragment with something more complicated?
> 
> > 	until($smtp = Net::SMTP->new("localhost")) {
> > 	   sleep(int(rand 60) + 1);
> > 	}
> > 
> > The actual delivery of mail to the final recipient is processed through
> > the queue just as if Sendmail had been invoked from the console and the
> > message piped to its STDIN as you suggest.
> 
> That depends on local policy.  It's also possible to have a system
> where there's no smtp listener but where sendmail is running and
> will deliver mail elsewhere.

This is actually what I would regard as the worst case scenario for your
approach.  If someone has Sendmail available and directly invokes it from
the console, there is no legitimate expectation that the message will ever
come out of the queue.  If Sendmail is not running as a daemon to do SMTP
listening, then it is quite likely that it is not running as a queue
processor.  As a result, messages in the queue may stay there forever. 

> > If you do not have an SMTP daemon on "localhost," then you can use
> > Net::SMTP to point to the smart remailer used on your network, which
> > will presumably also handle queue processing. This configuration is
> > impossible by direct invocation of Sendmail.
> 
> Note that /usr/lib/sendmail could be provided by smail (the case for
> the machine which is running the above perl fragment), or postfix, or
> whatever...

No, I am making a stronger assertion than that.  There need be no mail
system running on the web server machine whatsoever.  In such a case, the
only way to send mail from CGI is to connect over the network to a smart
remailer, and the best way to do this is to use Net::SMTP.

> > You also have much greater control over the message format when you use
> > Net::SMTP than if you invoke Sendmail directly.  For example, since the
> > web server usually runs as a low-privilege user ("www-data" on Debian,
> > "nobody" by default), setting the "from" information with the "-f" switch
> > when invoking Sendmail directly will cause the annoying "Authentication
> > Warning: www-data set sender to whatever" text to be included if you
> > attempt to use a valid bounce address, as is good practice.
> 
> Again, this behavior is determined by local administrative decisions (such
> as which implementation of /usr/lib/sendmail to use).  It's perfectly
> reasonable to have an implementation of /usr/lib/sendmail which does not
> inject messages into the headers, while having an smtp listener which
> does inject messages into the headers (and that's the kind of system
> which the above perl fragment came from).

This is precisely my objection: the command line syntax and switches for
Sendmail are not standardized.  Most of the basics are covered, but I have
no idea what would happen if your particular set of switches, "-oi -oem
-t," were passed to something like Smail.  SMTP is a network standard that
is defined across all vendors and platforms; the command line syntax of a
mailer and its return codes are not.

If we assume that the particular thing invoked by running a program called
"sendmail" from CGI is, in fact, the thing that is conventionally known as
"Sendmail" and which is contained in the Debian package of that name,
rather than a symbolic link to something else, then I think it is clear
that the end result is going to be authentication warning messages in the
headers of outgoing mail.  There are only two "local administrative" ways
to avoid this: (1) run the CGI program suid as a "trusted" user, which is
insane, or (2) add the web server owner uid ("www-data" for Debain,
"nobody" by default) as a trusted user, which is only a bit less insane.

In your example syntax, because you are not using the "-f" switch, you
will not generate an "authentication warning."  However, the sender
envelope address, to which bounces and delivery notification failures will
be sent, would be left as the process owner for the web server, such as
"www-data" or "nobody."  Assuming that a mail alias has been properly
configured for this, it is almost certainly going to be the mailbox of the
person responsible for the web server as a whole.  Especially on a web
server which has a lot of different virtual sites and many page authors,
this is probably extremely undesirable, and such a recipient may not even
be able to track down which CGI maintainer is responsible.

Using the Net::SMTP approach, there is complete freedom to set different
addresses for the sender evelope, the "From" header, the "Reply-To" 
header, and so on, and there are no security implications (such as whether
the sender is "trusted") to worry about. 

> > Finally, the use of Net::SMTP promotes independence of the Perl code
> > from mail program choices and even operating system choices. Sending
> > into the "localhost" SMTP port with Net::SMTP provides a consistent
> > interface regardless of whether the system runs Sendmail, Smail,
> > smtpd, or even Microsoft Exchange on Windows NT!
> 
> And running an smtp listener on a web server -- especially one which
> runs Sendmail -- is just one more thing to go wrong from a security
> point of view.
> 
> And, even if there is a smarthost, there's no reason to assume it's
> running on the local network.  A high-volume, robust web provider 
> may have a number of web servers, some of which are co-located in
> other cities.

Accepting your argument that running an SMTP listener on the web server is
a bad idea from a security point of view, what then is the best solution?
What you are proposing is that someone would have to install Sendmail,
configure it, and then manually modify the Debian-provided shell script
which starts Sendmail ("/etc/init.d/sendmail") so that it could be run as
a queue processing daemon but not an SMTP listening daemon.  This
implicates, I think, a Debian policy issue: it might be reasonable
(although, I contend, unnecessary) for the "cgi-scripts" package to
suggest the "sendmail" package, but certainly not to require hand-editing
the daemon start-up shell script to implement a configuration that is so
rarely used with Sendmail that the standard switches are hardcoded.  It is
important to remember that Sendmail will never take the mail out of the
queue if it is not running as some sort of daemon.

If someone regards Sendmail as a security risk on the web server, and I
agree that this might be an entirely reasonable view, then it is more
likely that they would either install no mail system at all, in which case
there would be nothing on the machine for you to invoke directly, or they
would install one of the "higher security" modular systems such as smtpd,
in which case your direct invocation method would not work.  Worse, if
someone chose to run one of these higher security or alternative mail
systems, and the "cgi-scripts" package suggested "sendmail," then this
would cascade through the package-dependency tables because the "sendmail"
package quite properly states "Conflicts: mail-transport-agent, smail."

As long as there is a smart host, then it makes no difference whether it
is on the local network.  The particular code example I gave, which would
work with any smart host simply by replacing "localhost" with the domain
name of the smart host, could certainly be made more robust by trying a
list of different smart hosts, and so on.  At some point, however, that
level of robustness begins to interfere with the tutorial value of the
examples included in the "cgi-scripts" package.

> > > In most (not all) cases, for cgi work, you want to use a mail system
> > > which queues mail.  In most cases where you need to use a mail system
> > > which does not queue mail you also don't want that mail being delivered
> > > from inside a cgi program.
> 
> > I agree here, but using Net::SMTP has several major advantages over
> > directly invoking Sendmail, and can fully preserve queue processing
> > when used appropriately. Your points are well-taken and I would
> > not recommend Net::SMTP if it did require the sacrifice of queue
> > processing.
> 
> Ok :)

I think we are in broad philosophical agreement about what is and is not
functionally desirable for a CGI script to do.  My issue is that we are
discussing this in the context of an example program in the Debian
"cgi-scripts" package, and we have to try to make this work on the
broadest possible range of systems without incurring package dependency
penalties unless they are absolutely necessary.  In particuar, if it is
not absolutely essential that an example CGI script invoke Sendmail, which
means that the "cgi-scripts" package is then in some way depenent upon the
"sendmail" package, this should be avoided. 

-- Mike



Reply to: