in reply to Insecurities in my scripting

I'd just like to expand a little on grep's comments above, to explain why this script could be used as a spam portal.

print MAIL "To: $form{'usermail'}\n";
Somebody could simply copy and paste an entire mailing list into the 'usermail' field and submit it.
The email would then be sent to everyone in that list.
victim1@domain.com, victim2@domain.com, victim3@domain.com, etc...
You get the picture.
This is made worse because the $form{'message'} is sent as the body of the email, meaning the (ab)user could enter their own adverts, urls etc into the 'message' field, so everyone would receive spam (possibly offensive) and it would appear to have been sent by you.

If you switch on taint mode

#!/usr/bin/perl -wT
Then perl will force you to run every user inputted data through a regex before you can send it outside of your program, such as to sendmail.
my $username; If ($form{username} =~ /^([\w.-]+)$/) { $username = $1; } else { die("invalid username"); }
See the regex docs for help.
You would need to run every user input through a regex. The difficult one is validating the email address, have a search around the monastery for help with that.

Replies are listed 'Best First'.
Re: Re: Insecurities in my scripting
by sulfericacid (Deacon) on Nov 20, 2002 at 10:16 UTC
    Are you virtually saying all I need to do is edit the first line, as i did below, for it to be more secure?

    #!/usr/local/bin/perl -wT use strict; # Let's have some fun my'ing things, shall me? my %form; my $sendmail; my $webmaster; my $yourname; my $thanks; use CGI; my $query = CGI->new; print $query->header; %form = %{$query->Vars}; $sendmail = "/var/qmail/bin/qmail-inject"; $webmaster = 'sulfericacid@qwest.net'; ( $thanks = <<'END_OF_THANKS' ) =~ s/^\s+//gm ; Thank you for visiting my website! Things are always changing so I hope you pop back again! If you asked any questions, please allow upto 24 hours for a response. END_OF_THANKS $yourname = 'Aaron'; # $signame = 'Aaron Anderson\n'; # $sigurl = 'www.yourdowmain.com\n"; ### Make sure things are being completed, die slackers! if ($webmaster eq "") { print "Webmaster, please include your email address!\n"; } if ($form{'usermail'} eq "") { print "Ok, buddy, how do you expect me to email you back if you FORGET + to leave yoru email address?!?\n"; } if ($form{'username'} eq "") { print "Please click back and type in your name so I can spy on you!\n" +; } if ($form{'message'} eq "") { print "Only a severe slacker would try to submit a form without leavin +g a message!\n"; } # Mail to Webmaster open (MAIL, '|-', "$sendmail -t") or die $!; print MAIL "To: $webmaster\n"; print MAIL "From: $form{'usermail'}\n"; print MAIL "Subject: Insert subject here!\n\n"; print MAIL "Name- $form{'username'}\n"; print MAIL "Url- $form{'userweb'}\n"; print MAIL "Message- $form{'message'}\n"; print MAIL "Ip- $ENV{'REMOTE_ADDR'}\n"; close (MAIL); # Mail to User open (MAIL, '|-', "$sendmail -t") or die $!; print MAIL "To: $form{'usermail'}\n"; print MAIL "From: $form{'weburl'}\n"; print MAIL "Subject: Thank you for signing my form!\n\n"; print MAIL "$thanks\n"; print MAIL "You said:\n"; print MAIL "$form{'message'}\n"; close (MAIL); # Let's give them something to look at, might as well, they were nice +enough to fill out the form! print <<end_of_results; <html> <head> <title>Results Page</title> </head> <table width="75%" border="0"> <tr> <td colspan="2"> <p>Thank you for filling out the form. If you are awaiting assis +tance and you asked a question, please allow upto 24 hours for my to get + back to you.</p> <p>- $yourname</p> </td> </tr> <tr> <td colspan="2"><font color="#9933CC">Here is a copy of what you s +ent...</font></td> </tr> <tr> <td width="9%"><font color="#666666">name:</font></td> <td width="91%"><font color="#999999">$form{'username'}</font></td +> </tr> <tr> <td width="9%"><font color="#666666">email:</font></td> <td width="91%"><font color="#999999">$form{'usermail'}</font></td +> </tr> <tr> <td width="9%"><font color="#666666">url:</font></td> <td width="91%"><font color="#999999"><a href="$form{'weburl'}">$f +orm{'weburl'}</a></font></td> </tr> <tr> <td width="9%"><font color="#666666">message:</font></td> <td width="91%"><font color="#999999">$form{'message'}</font></td> </tr> <tr> <td width="9%"><font color="#666666">Rec. IP:</font></td> <td width="91%"><font color="#999999">$ENV{'REMOTE_ADDR'}</font></ +td> </tr> <tr> <td width="9%">&nbsp;</td> <td width="91%">&nbsp;</td> </tr> </table> end_of_results

      If you set taint mode, your program will not be more secure, but Perl will warn you of (some) possible security problems. That is, Perl will refuse to run it if it thinks it is not secure enough.

      -- 
              dakkar - Mobilis in mobile
      
      Short answer: yes !

      However, once Taint mode is on, every piece of user entered data must be untainted, or your script will die if you try to pass that data onto an external program.

      This can only be done by assigning the value from $1 after successfully matching a regex.

      You could though, match anything with a regex such as ...
      warning: bad code

      if ( $form{usermail} =~ /(.*)/ ) { $form{usermail} = $1; }
      Taint mode will not complain, and you will be still passing insecure data to the sendmail program because that regex matched enything and everything.

      So, long answer: yes, but it's up to you to responsibly and thoughtfully untaint the data.

      As before, I recommend you read the regex tutorial to learn such things as assigning a match to $1.
      See this offsite Taint tutorial http://gunther.web66.com/FAQS/taintmode.html.

        Thanks fireartist for the info on tainting. I will look into those resources and will post another question if I get stumped.

        Thanks again!!

        sulfericacid
Re: Re: Insecurities in my scripting
by iburrell (Chaplain) on Nov 20, 2002 at 17:38 UTC
    Even worse, an attacker could put the entire messages and his own headers in the useremail parameter. Newlines are allowed in form parameters. The attacker could forge his own email headers and push the real message to the bottom.