# Archivists note: This script requires perl5 #!/usr/bin/perl -T ## ## rjsemail.cgi - Simple, Safe, Generic CGI backend mail script. ## ## by Robert Seymour . ## Copyright (c) 1995, 1996 Robert Seymour and Springer-Verlag. ## All rights reserved, this script may be distributed in ## electronic format and/or modified under the same terms as Perl ## itself. ## ## CPAN menu entry: # # File Name: rjsemail.cgi # File Size in BYTES: 5981 # Sender/Author/Poster: Robert J. Seymour # Subject: rjsemail.cgi - Simple, Safe, Generic CGI backend mail script. # # rjsemail.cgi provides a simple, safe, and generic backend for sending # electronic mail from a CGI program. This script is taint checked and # does not allow insipid commands to be executed or information to be # divulged through user inputted strings. You can use this script as a # common backend for all your mail sending (HTML page example included) # or use it as a guide to safe use of subprocesses in CGI programs. ## To use this script, you should create an HTML page (or script which ## generates an HTML page) with a submission form pointing to this script. ## An example of this is shown below: ## ## Submit Feedback ##

Submit Feedback

##

Please feel free to enter in feedback below:

##
## ##

Please enter in your email address:
## ##

##

Please input the subject of your message:
## ##

##

Please input the body of the message:
## ##

## ##

##
## ## ## You can also fix the subject header by making it a hidden field as ## well (and similarly for the other entries). Note also that you need ## not use the exact elements shown here, any HTML forms element which ## generates a string as a value (i.e. selection lists, popup menus, or ## others) will work. Don't forget to the set the "to" email address ## properly in your HTML page. ## Use the CGI::* modules for CGI, log, and HTML processing. use CGI::Carp; use CGI::Form; use strict; ## Variable initializations (for use strict). my($to,$admin,$from,$subject,$body,$sendmail,$query); ## Where is sendmail located. $sendmail = "/usr/lib/sendmail"; ## Set the path for security and taint checking. $ENV{'PATH'} = "/usr/bin:/bin"; ## Create a new query object for CGI and HTML parsing. $query = new CGI::Form(); ## If you want to hardcode any of these, just set them up by $sendmail ## in the constants section, they will only be overriden if unset by ## these statements. You might also choose to append to the message ## here to indicate that the from address is not verified. In general, ## I would advise you to set them in your pages, this lets the program ## work for many different pages or submissions. $to ||= $query->param("to"); $admin = $admin || $query->param("admin") || $query->param("to"); $from ||= $query->param("from"); $subject ||= $query->param("subject"); $body ||= $query->param("body"); ## Append a warning to the message about forgery and origin. $body .= <<"EOHF"; -- Message sent via rjsemail.cgi, sender's address may be forged. EOHF ## Start sendmail taking input on STDIN to be sent off. By using ## sendmail -oit and writing to it with a here file (as below), we ## avoid sh -c gotchas that backticks, system, or "| $mail $addr" ## can fall victim to. Searching for semi-colons isn't safe enough ## and trying to scrub user inputted fields is both difficult and ## hazardous. open(MAIL,"| $sendmail -oi -t") || do { print $query->header(); print $query->start_html(-title => "Error Sending Mail", -author => $admin); print "

Error Sending Mail

\n"; print "

Sendmail exited with error: $!, please go back in your\n"; print " browser and resubmit the email form or report the error\n"; print qq/ to the administrator, $admin<\/a>"\n/; print "

\n"; print $query->end_html(), "\n"; ## CGI::Carp makes semi-useful error entries in the httpd error log. die "Sendmail exited with error: $!\n"; }; ## Print message to sendmail filehandle. Note that you can't create ## a shell or escape out of this by entering in code to the text block ## or email fields (even backticks). The to address is taken from the ## submission form (use a hidden field) so that this same backend script ## can service any number of HTML submission forms. print MAIL <<"EOHF"; To: $to From: $from Subject: $subject X-Mailer: rjsemail.cgi 1.0 $body EOHF close(MAIL); ## Check exit status (the latter uses CGI::Carp). Give the user ## feedback through a HTML response. if($?) { print $query->header(); print $query->start_html(-title => "Error Sending Mail", -author => $admin); print "

Error Sending Mail

\n"; print "

Sendmail exited with error: $!, please go back in your\n"; print " browser and correct the email form or report the error\n"; print qq/ to the administrator, <$admin><\/a>"\n/; print "

\n"; print $query->end_html(), "\n"; ## CGI::Carp makes semi-useful error logs in the httpd log. croak "Sendmail exited with error: $!\n"; } else { print $query->header(); print $query->start_html(-title => "Thank You For Your Feedback", -author => $admin); print "

Thank Your For Your Feedback

\n"; print "

I appreciate your comments and will try to respond to\n"; print " your email shortly.\n

\n"; print $query->end_html(), "\n"; } ## End of rjsemail.cgi.