I have a form to signup yourself in a mailing list.
I had set up the script to send me a mail for every signup and confirmation.
The last days I saw a bunch of empty submissions (rejected). Turns out filter_input is that good :-)
But I want to see the input of the malicious users, so I'm encoding the input and sending it to me by mail
htmlentities($_POST['userName'], ENT_QUOTES, "UTF-8")
- Is that secure?
- Should I add mysql_real_escape_string() ?
- It is possible to craft a post in such a way that will be able to do any harm while sending the mail to me?
- I'm not writing rejected submisions to the database, only mailing them to me.
Here's the relevant code.
<?php
$userName = filter_input(INPUT_POST, 'userName', FILTER_SANITIZE_STRING);
$userEmail = filter_input(INPUT_POST, 'userEmail', FILTER_VALIDATE_EMAIL);
if(!checkdnsrr(array_pop(explode("@",$userEmail)),"A"))
$hostInvalido = true;
if(!empty($userName) && $userName!==FALSE && !empty($userEmail) && $userEmail!==FALSE && !isset($hostInvalido) ) {
//All ok
} else {
echo "Datos invalidos, por favor, intenta nuevamente.";
$fromaddress="info@example.com";
$fromname="Error reporting";
$to= "webmaster <webmaster@example.com>";
$subject="MailList: Error ";
$userName = htmlentities($_POST['userName'], ENT_QUOTES, "UTF-8"); // is this secure?
$userEmail = htmlentities($_POST['userEmail'], ENT_QUOTES, "UTF-8");
$body = "Nombre: $userName<br>Email: $userEmail";
$body .= (isset($hostInvalido)) ? "<br>Host invalido" : "";
$ret = send_mail($to, $body, $subject, $fromaddress, $fromnam开发者_开发问答e, $attachments=false);
}
// I'm including this function so you can analyze it for any possible vulnerability
function send_mail($to, $body, $subject, $fromaddress, $fromname, $attachments=false) {
$eol="\r\n";
$mime_boundary=md5(time());
# Common Headers
$headers = "";
$headers .= "From: ".$fromname."<".$fromaddress.">".$eol;
$headers .= "Reply-To: ".$fromname."<".$fromaddress.">".$eol;
$headers .= "Return-Path: ".$fromname."<".$fromaddress.">".$eol; // these two to set reply address
$headers .= "Message-ID: <".time()."-".$fromaddress.">".$eol;
$headers .= "X-Mailer: PHP v".phpversion().$eol; // These two to help avoid spam-filters
# Boundry for marking the split & Multitype Headers
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$mime_boundary."\"".$eol.$eol;
# Open the first part of the mail
$msg = "--".$mime_boundary.$eol;
$htmlalt_mime_boundary = $mime_boundary."_htmlalt"; //we must define a different MIME boundary for this section
# Setup for text OR html -
$msg .= "Content-Type: multipart/alternative; boundary=\"".$htmlalt_mime_boundary."\"".$eol.$eol;
# Text Version
$msg .= "--".$htmlalt_mime_boundary.$eol;
$msg .= "Content-Type: text/plain; charset=UTF-8".$eol; //iso-8859-1
$msg .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$msg .= strip_tags(str_replace("<br>", "\n", $body)).$eol.$eol; //mb_substr($body, (strpos($body, "<body>")+6))
# HTML Version
$msg .= "--".$htmlalt_mime_boundary.$eol;
$msg .= "Content-Type: text/html; charset=UTF-8".$eol;//iso-8859-1
$msg .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$msg .= $body.$eol.$eol;
//close the html/plain text alternate portion
$msg .= "--".$htmlalt_mime_boundary."--".$eol.$eol;
if ($attachments !== false)
{
for($i=0; $i < count($attachments); $i++)
{
if (is_file($attachments[$i]["file"]))
{
# File for Attachment
$file_name = mb_substr($attachments[$i]["file"], (strrpos($attachments[$i]["file"], "/")+1));
$handle=fopen($attachments[$i]["file"], 'rb');
$f_contents=fread($handle, filesize($attachments[$i]["file"]));
$f_contents=chunk_split(base64_encode($f_contents)); //Encode The Data For Transition using base64_encode();
$f_type=filetype($attachments[$i]["file"]);
fclose($handle);
# Attachment
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: ".$attachments[$i]["content_type"]."; name=\"".$file_name."\"".$eol; // sometimes i have to send MS Word, use 'msword' instead of 'pdf'
$msg .= "Content-Transfer-Encoding: base64".$eol;
$msg .= "Content-Description: ".$file_name.$eol;
$msg .= "Content-Disposition: attachment; filename=\"".$file_name."\"".$eol.$eol; // !! This line needs TWO end of lines !! IMPORTANT !!
$msg .= $f_contents.$eol.$eol;
}
}
}
# Finished
$msg .= "--".$mime_boundary."--".$eol.$eol; // finish with two eol's for better security. see Injection.
# SEND THE EMAIL
ini_set('sendmail_from',$fromaddress); // the INI lines are to force the From Address to be used !
$mail_sent = mail($to, $subject, $msg, $headers);
ini_restore('sendmail_from');
return $mail_sent;
}
?>
XSS injections is mainly javascript, so using htmlentities() is sufficient :)
If you are still worried, drop the message into a < textarea>< /textarea> and then mail it.
精彩评论