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

Hello, monks

I am having a problem with sendmail on a perlscript on my site. Strange, since I was following all the same examples, here is my sample code:

#!/usr/bin/perl use utf8; use warnings; use strict; use CGI; use Email::Valid; print "Content-type: text/html\n\n"; my $p = CGI->new(); my ($name, $mail, $text) = ($p->param('name'), $p->param('mail'), $p- +>param('text')); if ( $name && $mail && $text ) { if ( Email::Valid->address($mail) ) { #all is set: send to my mail open(MAIL, '|/usr/sbin/sendmail -t') or die("Can`t open sendma +il: $!\n"); print MAIL "Content-type: text/plain\n\n"; print MAIL 'info@difinancial.comdc.net'; print MAIL "From: $mail\n"; print MAIL "Name: $name\n"; print MAIL "Subject: $text"; close(MAIL); print "<h2>Mail send sucessful to 'info\@difinancial.comdc.net +.Thanks for query.</h2>"; } else { print "<p>Mail invalid</p>"; } } else { print "<p>Complete all forms.</p>"; }

There are no errors, I`ve added a check on  open(MAIL, '|/usr/sbin/sendmail -t') or die('....'); and the last printing to html document h2 tag is printed, but I don`t recieve any messages on my pointed mail. Any ideas?

You can test it, it`s temporaly set for testing on www.difinancial.comdc.net

Replies are listed 'Best First'.
Re: Sending a mail with Perl, nah.. the same and same question...
by Corion (Patriarch) on Mar 29, 2012 at 10:58 UTC

    To whom are you sending the mail?

    Also, you do not properly protect your script against malicious input and your script can easily be used to send arbitrary mail to arbitrary recipients. I won't tell you what, because that might result in you just filtering out bad input instead of only allowing specific, known good input. Please think long and hard about what kinds of input you want to allow, and write code to only allow that specific kind of input and reject all else.

    Also, consider using MIME::Lite or one of the Email modules instead of piping to sendmail yourself.

    Update: Also consider just using a well-known, good formmail script.

      Originally the input was handled by a javascript.

      This is only the serverside form.

        To reinforce what has been said by Corion and marto: never, ever trust input from the client. Validation done on the client side is only to optimize the input loop by reducing the number of round trips needed to the server.

        Assume that you client can (and will if you are really paranoid) put anything on the wire that they wish. I have had to fight the attitude that 'we are not dealing with smart hackers here' when doing code audits (previous life), and was constantly amazed at the lack of concern shown toward basic application security.

        --MidLifeXis

        A reply falls below the community's threshold of quality. You may see it by logging in.

        A spammer will not run Javascript but talk directly to your mail sending script. The most important checks are the checks run on the server. You should really consider using the premade formmail script instead of rolling your own. Client-side validation will break as soon as somebody has Javascript disabled (like me) or does not even use a browser to send data (like a spammer).

        So what's to stop someone writing a script to submit data to this server side script, bypassing your JavaScript?

      Well, I still can`t understand what`s the error for not sending mail ( ok, I got it it`s weak in security ) but I just want to know where exactly is the error for not sending it?

        I purposefully only gave you a vague hint as to where the part of "not sending" in your script lies. You will have to read my post and go through your script to find it. I still recommend MIME::Lite for sending mail instead of talking to sendmail directly.

        You could consider printing your output to the console to inspect what sendmail receives.

Re: Sending a mail with Perl, nah.. the same and same question...
by tobyink (Canon) on Mar 29, 2012 at 16:43 UTC

    Here's a handful of issues:

    • You forgot to include "To:" in front of the recipient's address.
    • You forgot to include a line break after the recipient address.
    • You do not check whether $name, $mail and $text contain line-breaks. You must make sure that they do not - otherwise your script has just become a spam gateway.
    • You include a double line-break after the "Content-Type" header which means that all the subsequent headers will be treated as body text, not headers.
    • Once you've corrected the Content-Type problem, your generated e-mail does not contain any body text. This may cause problems for some mail transfer agents. As a minimum, include a couple of line breaks after the subject line.

    ... seriously, just use a pre-written script, such as the NMS one that people have pointed you towards.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'