[Note to moderator, maybe the subject of this thread should be changed to something more descriptive]
I still think line 51 is the problem, but I don't post data to the same page normally and I don't feel like looking into it.
Anyway here is how I would do it based on many battles with spammers. Have an entry html page with the form. I appologize in advance form my form example. I am posting from a device with no web tools so there is a table or two in there that needs to be cleaned up.
contact.html:
Code: Select all
<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"><meta http-equiv="Content-Language" content="en-us"><title>Contact Us</title><meta name="description" content="Use this form to send an email message."></head> <body "bgcolor="#FFFFFF" text="#000000" link="#993333" vlink="#333399" alink="#006633"><font face="trebuchet ms,arial,helvetica"> <SCRIPT TYPE="text/javascript"><!-- hide script from old browsersfunction TestDataCheck(){ // extract data from the form and test it // before sending it to the php script for email var username = document.feedback.Username.value; var useremail = document.feedback.UserEmail.value; var subject = document.feedback.Subject.value; var msg=document.feedback.Comments.value; var returnval = true; // msg.replace=("'","|"); //can add some prefiltering like this// msg.replace=("\"","^");// document.feedback.Comments.value=msg; //update filtered text if (username.length<4) { alert("Please Enter Your Name."); returnval = false; } if (useremail.length<5) { alert("Please Enter Your Email Address."); returnval = false; } if (subject.length<2) { alert("Please Enter a Subject."); returnval = false; } return returnval;}// end script --></SCRIPT> <div align="center"> <center></font> <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" width="600"> <tr> <td valign="top" width="142" style="border-left-style:none; border-left-width:medium; border-right-style:solid; border-right-width:1; border-top-style:none; border-top-width:medium; border-bottom-style:none; border-bottom-width:medium"><!--mstheme--><font face="trebuchet ms,arial,helvetica"> <p> </p> </font></td> <td valign="top" width="5" style="border-right-style:none; border-right-width:medium; border-top-style:none; border-top-width:medium; border-bottom-style:none; border-bottom-width:medium"><!--mstheme--><font face="trebuchet ms,arial,helvetica"><!--mstheme--></font></td> <td valign="top" height="100%" style="border-right-style:none; border-right-width:medium; border-top-style:none; border-top-width:medium; border-bottom-style:none; border-bottom-width:medium" width="452"><!--mstheme--><font face="trebuchet ms,arial,helvetica"> <p>Contact us by leaving a message and we'll get back to you as soon as possible.</p> <form name="feedback" action="_mail.php" method="POST" onSubmit="return TestDataCheck()" > <p><strong>All information is kept strictly private:</strong></p> </font><table id="table1"> <tr> <td><font face="trebuchet ms,arial,helvetica">Your Name:</font></td> <td><font face="trebuchet ms,arial,helvetica"> <input type="text" size="35" maxlength="50" name="Username"></font></td> </tr> <tr> <td><font face="trebuchet ms,arial,helvetica">Your Email: </font></td> <td><font face="trebuchet ms,arial,helvetica"> <input type="text" size="35" maxlength="150" name="UserEmail"></font></td> </tr> </table> <table id="table2"> <tr> <td width="60"><font face="trebuchet ms,arial,helvetica">Subject: </font></td> <td><font face="trebuchet ms,arial,helvetica"> <input type="text" size="35" maxlength="150" name="Subject"></font></td> </tr> </table><font face="trebuchet ms,arial,helvetica"> <p><strong>Enter your message in the space provided below:</strong></p> <dl> <dd> <textarea name="Comments" rows="5" cols="42" style="text-align: left; line-height: 100%" maxlength="1000"></textarea></dd> <dd> </dd> </dl> <p align="center"> <input type=SUBMIT value="Send Message"> <input type="RESET"></p> </form> </font></td> </tr></table></body></html>
ok, that is the form. note the simple checking of the fields with a little javascript. Since anyone can see this don't put a lot of time in filtering here. This can all be bypassed by a spammer anyway. The other thing you see is the data is sent to _mail.php.
_mail.php:
Code: Select all
<?php
//Blocked IP Addresses
//Put IPs in here of addresses that try to insert spam
//The ips in this array are just examples (i did get spam attempts
//from them) but you should remove them and start fresh.
$blockedip=array("130.76.32.16","98.203.163.91","130.76.32.23"
,"77.87.152.62","77.92.88.9","89.76.164.52");
function InjectionAttempt($input) // this removes any injection characters
{
if (eregi("%0a", $input) ||
eregi("%0d", $input) ||
eregi("Content-Type:", $input) ||
eregi("bcc:", $input) ||
eregi("to:", $input) ||
eregi("cc:", $input))
{
return 1; // bastards
}
else
{
return 0;
}
}
function InjectionAttempt2($input) // use this for fields that contain return codes and line feeds
{
if (eregi("Content-Type:", $input) ||
eregi("bcc:", $input) ||
eregi("to:", $input) ||
eregi("cc:", $input))
{
return 1; // bastards
}
else
{
return 0;
}
}
function errormsg()
{
printf("<br><br>Sorry, the system failed to send message. Please avoid using the following in your entries:<br>to:<br>bcc:<br>cc:<br>or other non-ASCII characters<br><br>Press the back button and edit your message.");
return;
}
function errormsg2()
{
printf("<br><br>Sorry, the system failed to send message. Please avoid using links in your message or other non-ASCII characters<br><br>Press the back button and edit your message.");
return;
}
function stripjunk($sting,&$cnt) //change potential hacked user input fields like a bee
{
//This routine is very agressive and will alter innocent
//messages, but the meaning won't be lost
//$cnt returns a count of the number of the most suspicious characters
//you can modify this filter to suit your needs
for($i=0; $i<strlen($sting); $i+=1) //I used an old fashioned technique for clarity
{
if($sting[$i]==':') {$sting[$i]='-'; $cnt++;} // only count characters that could be in links
if($sting[$i]=='<') {$sting[$i]='.';}
if($sting[$i]=='>') {$sting[$i]='.';}
if($sting[$i]=='[') {$sting[$i]='.';}
if($sting[$i]==']') {$sting[$i]='.';}
if($sting[$i]=='{') {$sting[$i]='.';}
if($sting[$i]=='}') {$sting[$i]='.';}
if($sting[$i]==';') {$sting[$i]='.';}
if($sting[$i]=='*') {$sting[$i]='.';}
if($sting[$i]=='/') {$sting[$i]='.'; $cnt++;} // could be a link http://spam.com
if($sting[$i]=='\\') {$sting[$i]='.';}
if($sting[$i]=='%') {$sting[$i]='.';}
}
return $sting;
}
if(isset($_POST["Username"]) && isset($_POST["UserEmail"]))
{
// Incoming input: Username,UserEmail,Comments,Subject
// You can remove the printf and not post an error message just to keep them guessing
// You could also sanatize the fields and send the message to yourself for analysis, but be careful!
// You could save to a log file (safest) for a record and the track down the spammer later
if(InjectionAttempt($_POST["Username"]) ) {printf ("Problem with Name Field<br>%s",$_POST["Username"]); errormsg(); return;}
if(InjectionAttempt($_POST["UserEmail"]) ) {printf ("Problem with your Email Field<br>",$_POST["UserEmail"]); errormsg(); return;}
if(InjectionAttempt2($_POST["Comments"]) ) {printf ("Problem with Comments<br>",$_POST["Comments"]); errormsg(); return;}
if(InjectionAttempt($_POST["Subject"]) ) {printf ("Problem with the Subject field<br>",$_POST["Subject"]); errormsg(); return;}
//loop through IP list to block
//if you don't post error messages or redirect spam attempts
//you can add persistant spammers or abusers to the blocked list
//be careful because you can also block legit people sharing the ip
$block=0;
foreach($blockedip as $hit)
{
if(strcmp($_SERVER['REMOTE_ADDR'],$hit)==0) $block=1;
// Since this could be a valid message, just tag it, but send
// the message with the blocked ip notice. If needed, you could put
// some code in here to redirect this user to a html page
// that tells them due to abuse they are blocked...
}
$spam_cnt=0; // count the number of insertions detected in function stripjunk
$username=stripjunk($_POST["Username"],$spam_cnt);
$useremail=stripjunk($_POST["UserEmail"],$spam_cnt);
$comments=stripjunk($_POST["Comments"],$spam_cnt);
$subject = "Feedback: ".stripjunk($_POST["Subject"],$spam_cnt);
// To avoid users inserting really long strings, make the truncated
// you can also limit them in the html input form
if(strlen($username)>40) $username=substr($username,0,40); // truncate strings
if(strlen($useremail)>150) $useremail=substr($useremail,0,150);
if(strlen($subject)>150) $subject=substr($subject,0,150);
if(strlen($comments)>1000) $comments=substr($comments,0,1000);
//build the message to yourself
$content = "\nNAME:\n".$username;
$content .= "\n\nEmail:\n".$useremail;
$content .= "\n\nMESSAGE:\n".$comments;
$content .= "\n\nSent:\n".date("l dS F Y h:i:s A")." PST";
$content .= "\nSent from: ".$_SERVER['REMOTE_ADDR'];
if($block) $content .= "\nIP BLOCKED\n";
//Build the email header
$from="you@domian.com"; //this is really from your site to you
$from_name = "First Last"; // Plain Text Name for Email Address
$eol="\r\n";
$headers = "Reply-To: ".$from_name."<".$from.">".$eol;
$headers.= "From: ".$from_name."<".$from.">".$eol;
$headers.= "Content-type: text/plain".$eol;
$headers.= "Message-ID: <".time()."-".$from.">".$eol;
//There are tons of sites about email headers and mime formats, but this seems to work
if($spam_cnt>5)
{
//probably spam, several hits occurred when calling stripjunk
//I usually email these messages anyway because their message
//is sanatized. This way I can track the IP and see if they
//are trying anything new.
//However this example rejects them
if(stristr($comments,"http")!=FALSE) // does http appear in the text?
{
errormsg2(); // this is for sure spam attempt reject.
return;
}
}
// SEND THE EMAIL
$to="you@your.domain";
ini_set(sendmail_from,$from); // the INI lines are to force the From Address to be used !
$returnpath="-f ".$from; // Forces the return path to be configured properly
$mail_sent = mail($to, $subject, $content, $headers, $returnpath);
//Note I don't do any error checking on $mail_sent because mail() often produces strange return codes yet works
//Tell them they are blocked (even though you allowed
//the message through) to discourage future attempts
if ($block==0) header('Location: http://www.example.com/_thankyou.htm');
else header('Location: http://www.example.com/_block.htm');
}
?>
Ok, this is where all the work is done. Read the comments, modify it to your system, and try it. I appologize again if there are any typos because I can't test it on this device.
This php script formats the form data and sends it to you. I know you need something different but I think this code is generic enough to jump start you. By the way his script is very agressive against spammers and is definately overkill.
Let me know how it goes and if you find any errors/problems. Then we can move on to the database if you want. However, I'm thinking maybe it would be easier for you just to keep copies of the outgoing messages as a record. It isn't like you are recording sales or have a members login where this information gets used over and over.
Edit: I just realized some extra field checks were dropped during the cut/paste action. They aren't critical for now but I'll post the complete thing later. Gotta go SEE THE _MAIL.PHP posted below for an additional filter to check for vaild email addresses (not critical, but helpful)