Nkuvu has asked for the wisdom of the Perl Monks concerning the following question:
Edit Retitled per sporty's Consideration, was "Yet another Taint question".
I've Super Searched for Taint, and Mail::Mailer, and security, but haven't found the answer to my question. I have a general understanding of the risks involved in passing untainted data to a command, and I think I've taken decent precautions to untaint user data. Almost every single thread I've read on tainting and security have output that feeds into a database at some time. But I don't think that bit applies to the purpose of my script. This is a "contact me" script only. I'm not concerned if any or all of the fields are blank -- and you can see that I assign values if they are blank. The emails I receive from this script will never go into a database, so I've done nothing to protect against the SQL issues I read about so frequently. Every thread I've read seems to be so close to answering what I want to know that I feel like I shouldn't be asking this -- but it's been an issue rattling around in my skull for some months now, and I haven't seen it addressed yet. (Not that I'm saying it hasn't been addressed, just that I haven't seen it.)
But I'm still not sure my script is sound. And since I'm pretty new to writing scripts of this type I wanted to hear some criticisms and suggestions on my code.
The script is fed by another page that has the form -- I actually have a few different web pages feeding this script with different formats (I have a few pages that are not linked or related to the others, and wanted a different look and feel for them). But suffice it to say that the parameters are being passed in correctly. This script is working fine, I get emails just like I'm supposed to, and the validations seem to be working in accordance with what I expect. But the problem is that I'm not totally sure what to expect, or what to view as dangerous.
I've heard a lot of times that I need to choose a good set of characters for untainting data. But I'm not really sure what a good set of characters is for something like Mail::Mailer. Do I have to worry about shell escapes in the body? Is the list of characters allowed in the body (or subject, or name) too loose? Do I need to be concerned with the null byte issue that Ovid talks about in his CGI tutorial? I'm not really familiar with the modules I'm using here. I've read the docmentation, and taken heed of the warning "untaint user data to something acceptable". I'm still not sure if what I am doing with Mail::Mailer and Email::Valid are safe practices.
General comments on style or anything else are also welcome. Please ask if you want to see the forms that feed this, but I assure you they're quite trivial.
#!/usr/bin/perl -wT use strict; use Mail::Mailer; use Email::Valid; use CGI qw/:standard escapeHTML/; # used for debugging, commented out for live code #use CGI::Carp qw(fatalsToBrowser); $ENV{'PATH'} = '/bin:/usr/bin:/sbin'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my ($mailer, $from, $email_address, $to_address, $subject, $body); my ($tainted_from, $tainted_email, $tainted_subject, $tainted_body); # I amuse myself so easily my @random_senders = ( 'a giant purple monkey', 'frozen waffles', 'a group of rabid penguins', 'albuquerque', 'a fluorescent dog', 'a black moldy banana', 'planet zod', ); # Get the input values $tainted_from = param('from'); # User supplied name, not email addy $tainted_email = param ('email'); $tainted_subject = param('subject'); $tainted_body = param('body'); # Do some untainting ($from) = $tainted_from =~ /^([\w\-\.\s]+)$/ if $tainted_from; if ($tainted_email and Email::Valid->address($tainted_email)) { # Is this safe? $email_address = $tainted_email; } else { $email_address = 'Nobody@Nowhere.com'; } ($subject) = $tainted_subject =~ /^([\w\s\.,\?\'\!]+)$/ if $tainted_subject; # This is just getting silly: $tainted_body =~ s![^\w\s\d.,?\!\$\@~\'\"\#\%\&\^\(\)\[\]\{\};:\\/~\*\-\+]!!g if $tainted_body; $body = $tainted_body || "I have nothing intelligent to say."; # Set default values if the input was blank or bad $from = $random_senders[int(rand(scalar @random_senders))] if not $from; $subject = "Aliens speaking through $from say \"".( $subject ? $subject : "Kumquat!")."\""; # Hardcode my address, I always send it to one place $to_address = 'my@address.com'; # This does the actual mail sending $mailer = Mail::Mailer->new(); $mailer->open({ From => $email_address, To => $to_address, Subject => $subject, }) or die "Can't open: $!\n"; print $mailer $body; $mailer->close(); # Show the user some spiffy results. print header, title("Message results"), start_html, p("Message sent successfully!"), p("Your email:",br,$email_address), p("Subject:",br,$subject), p("Body:",br,pre(escapeHTML($body))), p("Note that if those aren't the values ", "you put in, they didn't pass through", "my validation filters. Or you were too", "lazy to actually put in any values."), end_html;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Yet another Taint question
by Zaxo (Archbishop) on Jun 26, 2004 at 05:03 UTC | |
by Nkuvu (Priest) on Jun 26, 2004 at 05:19 UTC | |
by Zaxo (Archbishop) on Jun 26, 2004 at 05:24 UTC | |
by Nkuvu (Priest) on Jun 26, 2004 at 05:28 UTC |