http://www.perlmonks.org?node_id=150088

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

I'm just trying to figure out how to make an email script, I pieced this together, it doesn't have any errors when I run it in Unix but I get an error 500 when I have a form submit to it online. Let me know what to do, Thanks!

#!/usr/bin/perl use CGI qw/:standard/; $to = "webmaster\@3dwc.com"; $from = "Customer\@fast-trak.com"; $subject = "Online Repair Status Inquiry"; $ok_url = "/thanks.html"; $bad_url = "/nogo.html"; $firstname=param('firstname'); $lastname=param('lastname'); $phone=param('phone'); $phone2=param('phone2'); $email=param('email'); $brand=param('brand'); $model=param('model'); $serial=param('serial'); $service=param('service'); @comments=param('comments'); open(MAIL, "|/usr/lib/sendmail -t") || die "cant run sendmail"; print MAIL "To: $to \n"; print MAIL "From: $from ($firstname)\n"; print MAIL "Subject: $subject \n\n"; print MAIL "$firstname"; print MAIL "$lastname"; print MAIL "$phone"; print MAIL "$phone2"; print MAIL "$email"; print MAIL "$brand"; print MAIL "$model"; print MAIL "$serial"; print MAIL "$service"; print MAIL "@comments"; close(MAIL); print "Location: $ok_url";

Replies are listed 'Best First'.
• WARNING security hole was (Re: Simple Email Script)
by merlyn (Sage) on Mar 07, 2002 at 19:31 UTC
    Ow! If you don't know what you're doing, please don't put random CGI scripts up on a net-available server!

    In particular, this combination of lines:

    $firstname=param('firstname'); ... print MAIL "From: $from ($firstname)\n";
    means that I can pass a newline-embedded string in the firstname parameter, and get a remote spam-sender or denial-of-service annoyer, courtesy of your script.

    Please. CGI is not for casual users.

    -- Randal L. Schwartz, Perl hacker

Re: Simple Email Script
by dorko (Prior) on Mar 07, 2002 at 19:34 UTC
      Don't half-use CGI. Go all the way:   print CGI::redirect($ok_url);
Re: Simple Email Script
by mrbbking (Hermit) on Mar 07, 2002 at 21:14 UTC
    You should use Taint mode in your CGI scripts and check all input for dangerous things before using it.
    Suggestion: Change your shebang line to enable warnings and Taint mode, like this:
    #!/usr/bin/perl -wT
    And then check all your input with regexes (un-taint it) to be sure that there's nothing scary in there.
    $firstname =~ /^([\w ]+)$/; $firstname = $1; if( length($firstname) < 1){ $firstname = "no valid name provided"; } # now $firstname contains only # numbers, letters, spaces and underscores.
    The particular regex I used may not meet your needs, and sanitizing the other pieces may be more difficult, but this is the general idea I think you'll want.

    Oh, to reply more to the question you actually asked - add this: "use CGI::Carp( 'fatalsToBrowser' );" to your script while you're debugging. Then you'll get a better description than "HTTP 500" when things go wrong.

    Good luck!

      And I'll save merlyn some time by pointing out that fatalsToBrowser should be used only while testing, not in production because it gives the bad guys more information than you want to give them. :)

      ..Guv

        In the NMS programs we originally used the CGI::Carp set_message() method to conditionally output the actual error message if a $DEBUGGING variable was set - thus retaining the ability to catch fatal errors (and be able to use 'die' in the programs without getting a 500 status) and control what information that gets emitted to the user. We subsequently discovered that set_message() wasn't available in older versions of CGI::Carp so we have provided our own cut-down version.

        /J\

Re: Simple Email Script
by gellyfish (Monsignor) on Mar 07, 2002 at 21:20 UTC

    Stick use strict; in there and use CGI::Carp qw(fatalsToBrowser);, make the 'shebang line' #!/usr/bin/perl -wT, then fix the problems - you will find the answers by searching this site.

    /J\

Re: Simple Email Script
by silent11 (Vicar) on Mar 07, 2002 at 19:54 UTC
    print "Location: $ok_url";
    should be print "Location: $ok_url\n\n"; -Silent11
Re: Simple Email Script
by einerwitzen (Sexton) on Mar 07, 2002 at 19:21 UTC
    update: the script works, (sends the email) but i guess it errors when forwarding the URL?