Forum Moderators: coopster
I've been using this code (or similar) for a while now on several sites. Today, my host switched one site off saying the this code is being exploited. I can see no reference to this in the site logs and have no problems with it on other sites.
Can anybody see anything obviously insecure with this:
<?PHPsession_start();
error_reporting(7);
#----------
# Set Variables
$formfailed = false;
$_SESSION['user'] = $_POST['user'];
$_SESSION['email'] = $_POST['email'];
$_SESSION['telephone'] = $_POST['telephone'];
$_SESSION['address'] = $_POST['address'];
$_SESSION['how'] = $_POST['how'];
$_SESSION['message'] = $_POST['message'];
$_SESSION['submit'] = $_POST['submit'];
$_SESSION['error'] = '';
$_SESSION['formfailed'] = false;
#----------
# Validate: String
function check_string($value, $low, $high, $mode, $optional)
{
if ( (strlen($value) == 0) && ($optional === true) ) {
return true;
} elseif ( (strlen($value) >= $low) && ($mode == 1) ) {
return true;
} elseif ( (strlen($value) <= $high) && ($mode == 2) ) {
return true;
} elseif ( (strlen($value) >= $low) && (strlen($value) <= $high) && ($mode == 3) ) {
return true;
} else {
return false;
}
}
#----------
# Validate: Email
function check_email($email, $optional)
{
if ( (strlen($email) == 0) && ($optional === true) ) {
return true;
} elseif ( eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $email) ) {
return true;
} else {
return false;
}
}
#-----------
function spamcheck($teststr) {
if (eregi('mime-version',$teststr) ¦¦ eregi('content-type',$teststr) ¦¦ eregi('bcc:',$teststr)) {
$emailBody = "Name: " . $_POST['user'] . "\n"
. "Email: " . $_POST['email'] . "\n"
. "Phone: " . $_POST['telephone'] . "\n"
. "Address: " . $_POST['address'] . "\n"
. "Wedding: " . $_POST['wedding'] . "\n"
. "Commercial: " . $_POST['commercial'] . "\n"
. "Lifestyle: " . $_POST['lifestyle'] . "\n"
. "Brochure: " . $_POST['brochure'] . "\n"
. "How Did You Hear About Us " . $_POST['how'] . "\n"
. "Message: " . $_POST['message'] . "\n"
. "\n"
. "--\n"
. "" . $_SERVER['HTTP_USER_AGENT'] . "\n"
. "" . $_SERVER['REMOTE_ADDR'] . "\n"
. "" . date('Y-m-d H:i:s') . "\n";
$emailHeader = "From: server@domain.co.uk\n"
. "Reply-To: nobody@nobody.com\n"
. "MIME-Version: 1.0\n"
. "Content-type: text/plain; charset=\"ISO-8859-1\"\n"
. "Content-transfer-encoding: quoted-printable\n";
mail('me@mydomain.co.uk','Attempted Hack', $emailBody, $emailHeader);
header ("Location: http://www.domain.co.uk/index.php");
exit;
}
}
#--------------------------------------------------------
# RegisterGlobals OFF
$FTGuser = $_POST['user'];
$FTGemail = $_POST['email'];
$FTGtelephone = $_POST['telephone'];
$FTGaddress = $_POST['address'];
$FTGwedding = $_POST['wedding'];
$FTGcommercial = $_POST['commercial'];
$FTGlifestyle = $_POST['lifestyle'];
$FTGbrochure = $_POST['brochure'];
$FTGhow = stripslashes($_POST['how']);
$FTGmessage = stripslashes($_POST['message']);
# Check inputs
spamcheck($FTGuser);
spamcheck($FTGemail);
spamcheck($FTGtelephone);
spamcheck($FTGaddress);
spamcheck($FTGwedding);
spamcheck($FTGcommercial);
spamcheck($FTGlifestyle);
spamcheck($FTGbrochure);
spamcheck($FTGhow);
spamcheck(FTGmessage);
# Fields Validations
$validationFailed = false;
if ( (! check_string($FTGuser, 1, 200, 3, false))) {
$validationFailed = true;
$_SESSION['error'] = 'Your name must be between 1 and 200 characters long';
}
else if ( (! check_email($FTGemail, false))) {
$validationFailed = true;
$_SESSION['error'] = 'Your email address is invalid';
}
else if ( (! check_string($FTGtelephone, 1, 200, 3, true))) {
$validationFailed = true;
$_SESSION['error'] = 'Telephone number can not be longer than 20 characters';
}
else if( (! check_string($FTGaddress, 1, 200, 3, true))) {
$validationFailed = true;
$_SESSION['error'] = 'Address can not be longer than 200 characters';
}
else if( (! check_string($FTGhow, 1, 200, 3, true))) {
$validationFailed = true;
$_SESSION['error'] = 'The How Did You.. field can not be longer than 200 characters';
}
else if ( (! check_string($FTGmessage, 1, 1000, 3, true))) {
$validationFailed = true;
$_SESSION['error'] = 'Your message but can not be longer than 1000 characters';
}
# Redirect user to the error page
if ($validationFailed == true) {
$_SESSION['formfailed'] = true;
header("Location: ../contact.php");
exit;
}
# Email to Form Owner
$emailTo = '"Owner Name" <owner@domain.co.uk>';
$emailSubject = "Contact Form Submission";
$emailBody = "A form has just been submitted:\n"
. "\n"
. "Name: $FTGuser\n"
. "Email: $FTGemail\n"
. "Telephone: $FTGtelephone\n"
. "Address: $FTGaddress\n"
. "Wedding: $FTGwedding\n"
. "Commercial: $FTGcommercial\n"
. "Lifestyle: $FTGlifestyle\n"
. "Brochure: $FTGbrochure\n"
. "How Did You Hear About Us?: $FTGhow\n"
. "Message: $FTGmessage\n"
. "\n"
. "--\n"
. "This is for information only:\n"
. "" . date('Y-m-d H:i:s') . "\n"
. "" . $_SERVER['REMOTE_ADDR'] . "\n"
. "" . $_SERVER['HTTP_USER_AGENT'] . "\n"
. "\n"
. "";
$emailHeader = "From: owner@domain.co.uk\n"
. "Reply-To: owner@domain.co.uk\n"
. "MIME-Version: 1.0\n"
. "Content-type: text/plain; charset=\"ISO-8859-1\"\n"
. "Content-transfer-encoding: quoted-printable\n";
mail($emailTo, $emailSubject, $emailBody, $emailHeader);
# Confirmation Email to User
$confEmailTo = $FTGemail;
$confEmailSubject = "Thank You";
$confEmailBody = "Dear $FTGuser\n"
. "\n"
. "Thank you for contacting Owner Website. I'll get back to you as soon as possible.\n"
. "\n"
. "Regards\n"
. "\n"
. "Owner";
$confEmailHeader = "From: owner@domain.co.uk\n"
. "Reply-To: owner@domain.co.uk\n"
. "MIME-Version: 1.0\n"
. "Content-type: text/plain; charset=\"ISO-8859-1\"\n"
. "Content-transfer-encoding: quoted-printable\n";
mail($confEmailTo, $confEmailSubject, $confEmailBody, $confEmailHeader);
# Redirect user to success page
header("Location: ../contact.php");
exit;
# End of PHP script
?>
Your help would be much appreciated.
Cheers
if (eregi('mime-version',$teststr) ¦¦ eregi('content-type',$teststr) ¦¦ eregi('bcc:',$teststr) [b]¦¦ eregi('cc:',$teststr)[/b]) {
By emailing the "injection attempt" to yourself, you are still allowing the injection attack to go through. It should really be logged to a DB or txt file if you want to see the attack, then an email sent to you that includes no user input with a generic "Caught another one! Go check the blah, blah place."
That's an awful lot of code to chew through though, so I didn't do a comprehensive analysis. Hope this helps... :)
PHP header injection attacks work when the user provides headers which are passed, unfiltered, to the mail function.
So, whether you address the mail function to send the "payload" of the attack to yourself or to someone else, the attack still occurs.
A recent discussion (and a thread from the library [webmasterworld.com]) I highly recommend for anyone experiencing the problem:
Combatting Webform hijack [webmasterworld.com]
"My webform has been hijacked. Any suggestions how to make this form secure?"