...

View Full Version : Resolved Prevent email form from being sent if URL is provided in message



optimus203
12-21-2010, 11:50 PM
Trying to prevent spam here. I need a function that will spit out an error message if http:// or www or <a href> is entered in message body. Any ideas?

Here is the form I've got now.



<?php
$name = $_POST['name'] ;
$email = $_POST['email'] ;
$phone = $_POST['phone'] ;
$find = $_POST['find'] ;
$subject = $_POST['subject'] ;
$message = $_POST['message'] ;
$verify = $_POST['verify'] ;

$body = "From: $name\n Email: $email\n Phone: $phone\n How They Found The Site: $find\n\n Message: $message";

function is_valid_email($email) {
return preg_match('#^[a-z0-9.!\#$%&\'*+-/=?^_`{|}~]+@([0-9.]+|([^\s]+\.+[a-z]{2,6}))$#si', $email);
}

function contains_bad_str($str_to_test) {
$bad_strings = array(
"content-type:"
,"mime-version:"
,"multipart/mixed"
,"Content-Transfer-Encoding:"
,"bcc:"
,"cc:"
,"to:"
);

foreach($bad_strings as $bad_string) {
if(eregi($bad_string, strtolower($str_to_test))) {
echo "$bad_string found. Suspected injection attempt - mail not being sent.";
exit;
}
}
}

function contains_newlines($str_to_test) {
if(preg_match("/(%0A|%0D|\\n+|\\r+)/i", $str_to_test) != 0) {
echo "newline found in $str_to_test. Suspected injection attempt - mail not being sent.";
exit;
}
}

if($_SERVER['REQUEST_METHOD'] != "POST"){
echo("Unauthorized attempt to access page.");
exit;
}

if(!is_valid_email($email)) {
echo '<h1 class="headerTop">Sorry. An Contact Form Error Has Occured</h1>
<p>Be sure to enter your name, email address, and a message. All fields marked with <strong>*</strong> are required.</p>
<p><a href="http://www.website.com">Click Here</a> to go back to contact form.</p>
<div class="spacer150"></div>';
exit;
}

contains_bad_str($email);
contains_bad_str($subject);
contains_bad_str(body);

contains_newlines($email);
contains_newlines($subject);


mail( "email@email.com", "Email from website - $subject", $body);
header( "Location: http://www.website.com/headerlocation.php" );
?>

I would also like to have a properly formatted error page for the if(!is_valid_email($email)) portion, but how would you point to a page like contacterror.php? I tried doing the following but did not work:



if(!is_valid_email($email)) {
include ('contacterror.php');
}

Fou-Lu
12-22-2010, 12:31 AM
You don't point to the error page, you would actually redirect. In order to do so, you need to ensure that no output has occurred prior to this point:


if(!is_valid_email($email)) {
header('Location: http://yoursite.com/contacterror.php');
exit();
}

Note that officially you need a fully qualified url to your redirect, though most browsers should understand a relative 'contacterror.php' name. I recommend full, even if you use variables to store 'http://yoursite.com/' in.

As for detecting links, this can go from something easy to something complicated really quickly.
In the simplest terms:


#(http(s?))|(www)\.#

would look for text starting with http(s) or www. In more complex terms:


((ht|f)tp(s?)\:\/\/|~/|/)?([-\w\.]+)+(:\d+)?(:\w+)?(@\d+)?(@\w+)?([-\w\.]+)(/([\w/_\.]*(\?\S+)?)?)?

would break down the protocol, ssl, domain with potential user and password parts, and paths through to extensions. These are both preg patterns, and can be used within a preg_match, though on bodied text you need to enable the multiline modifier (m).

Note that I retrieved that pattern off of the net and took a quick scan over what it does. It appears to match fairly closely to the specifications of the URI, though I have a feeling that it could go a couple below.

optimus203
12-22-2010, 03:29 AM
So how would I go about implementing this? I'm really underdeveloped with php, but working on getting better. Tried this statement, but doesn't work. Getting syntax error.



if(preg_match("((ht|f)tp(s?)\:\/\/|~/|/)?([-\w\.]+)+(:\d+)?(:\w+)?(@\d+)?(@\w+)?([-\w\.]+)(/([\w/_\.]*(\?\S+)?)?)?", $message) {
echo "Sorry. No url's allowed in message. Please go back and try again.";
exit;



Here is the revised code overall. The $str_to_test variable should be referring to one of the 6 $_POST values, correct? Not sure about that part. I got this script from another site and I'm trying to transfer over to my needs.


<?php
$name = $_POST['name'] ;
$email = $_POST['email'] ;
$phone = $_POST['phone'] ;
$find = $_POST['find'] ;
$subject = $_POST['subject'] ;
$message = $_POST['message'] ;

$body = "
From: $name\n
Email: $email\n
Phone: $phone\n
How They Found The Site: $find\n\n
Message: $message";

function is_valid_email($email) {
return preg_match('#^[a-z0-9.!\#$%&\'*+-/=?^_`{|}~]+@([0-9.]+|([^\s]+\.+[a-z]{2,6}))$#si', $email);
}

function contains_bad_str($str_to_test) {
$bad_strings = array("content-type:","mime-version:","multipart/mixed","Content-Transfer-Encoding:","bcc:","cc:","to:");

foreach($bad_strings as $bad_string) {
if(eregi($bad_string, strtolower($str_to_test))) {
echo "$bad_string found. Suspected injection attempt - mail not being sent.";
exit;
}
}
}

function contains_newlines($str_to_test) {
if(preg_match("/(%0A|%0D|\\n+|\\r+)/i", $str_to_test) != 0) {
echo "newline found in $str_to_test. Suspected injection attempt - mail not being sent.";
exit;
}
}


if($_SERVER['REQUEST_METHOD'] != "POST"){
echo("Unauthorized attempt to access page.");
exit;
}


// Checks for URL inserts into message body
if(preg_match("((ht|f)tp(s?)\:\/\/|~/|/)?([-\w\.]+)+(:\d+)?(:\w+)?(@\d+)?(@\w+)?([-\w\.]+)(/([\w/_\.]*(\?\S+)?)?)?", $message) {
echo "Sorry. No url's allowed in message. Please go back and try again.";
exit;
}


// Checks to make sure valid email has been entered
if(!is_valid_email($email)) {
header('Location: http://www.website.com/error.php');
exit;
}

contains_bad_str($email);
contains_bad_str($subject);
contains_bad_str(body);

contains_newlines($email);
contains_newlines($subject);

mail( "email@email.com", "Email from website - $subject", $body);
header( "Location: http://www.website.com/confirm.php" );
?>


I appreciate the help.

Fou-Lu
12-22-2010, 02:08 PM
You need to add #, /, or another type of character to the start and end of the pattern. That should work then, you will likely need a m modifier to make it work with multiple lines.

optimus203
12-23-2010, 03:24 AM
Thanks Fou. That helped resolve the issue.

There were some other major faults with the script that I was able to resolve on my own. Thanks again for the help.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum