Jump to content

How to make contact forms more secure?


simcoweb

Recommended Posts

Hi everyone. Been gone for awhile but always know I can get answers here :)

 

I have a script i've used over and over for processing forms. It does validation via 'if' statements and works quite well in that respect. Emails are sent to both the person completing the form and the site owner in a plain text format. And, the form has CAPTCHA security as well. However, it seems the spammers have ways to exploit the form code itself without having to deal with the CAPTCHA in many cases. I'm not sure what additional steps I can employ in the code that would prohibit header injections and other malicious crap that they use. Perhaps a referrer check of some sort? An electronic shock sent through their keyboard if they try to spam? I cruised through the boards and didn't find anything specific and wondered who has some insight and examples of this. Any help is always appreciated!

Link to comment
Share on other sites

Absolutely! Here's the whole thing in a nutshell:

 

<?php
session_start();
// Turn on magic quotes to prevent SQL injection attacks
if(!get_magic_quotes_gpc())
set_magic_quotes_runtime(1);

if (isset($_POST['submitted']))	 {
// get form data
$name = strip_tags(trim($_POST['full_name']));
$email = strip_tags(trim($_POST['email']));
$phone = strip_tags(trim($_POST['phone']));
$comments = strip_tags(trim($_POST['comments']));
$match = $_SESSION['contact']; // the code on the image
$secure = strtoupper(trim(strip_tags($_POST['secure'])));
$today = date("F j, Y, g:i a");

// some validation
$errors = array();

// input error checking
    if ($name=="") {
        $errors[] = "Please enter your full name.<br/>";
    }
    if ($phone==""){
  $errors[] = "Please enter your phone number.<br/>";
}
if ($email=="") {
        $errors[] = "Please provide your email address<br>";
    }
    if ($email) {
        if (!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email)) {
            $errors[] = $email. " is not a valid email address. Please enter a valid email address.<br/>";
        	}
        }
	if (!$secure) {
        $errors[] = "No security code entered<br/>";
    }
    if (($secure!=$match) && ($secure!="")) {
        $errors[] = "Security code mismatch. Please re-enter.<br/>";
    } 
    if (!$errors) {

// start mail process
$mailContent="--------CONTACT--------\n"
            ."Name: ".$name."\n"
            ."Date: ".$today."\n"
            ."E-mail: ".$email."\n"
            ."Phone: ".$phone."\n"
            ."Description: ".$comments."\n";
//----------------------------------
$toAddress="info@domainname.com"; /* change this! */
$subject="Your Site Inquiry"; /* change this! */
$recipientSubject="Your Site Inquiry"; /* change this! */
$receiptMessage = "Thank you ".$name." for inquiring at LenderFish.com's website!\n\n\nHere is the contact information you submitted to us:\n\n"
            ."--------CONTACT--------\n"
            ."Name: ".$name."\n"
            ."E-mail: ".$email."\n\n--------PHONE--------\n"
            ."Phone: ".$phone."\n"
            ."Comments: ".$comments."\n";
//----------------------------------
mail($email, $subject, $receiptMessage,"From:$toAddress");
//----------------------------------
mail($toAddress,$recipientSubject,$mailContent,"From:$email");
header("Location: success.php");
}
}
?>

Link to comment
Share on other sites

- consider using htmlentities() on your input

- i would also use an if on the first and second mail before relocating to success.php, this way you are also able to relocate to failed.php for example

- use a token to make sure they did use the form (when they click the submit button, the token is set)

- reverse your check on "if (($secure!=$match) && ($secure!=""))" if the first failed the second won't even be evaluated

- "if ($email == "") {} if ($email) {}" can easily be written as "if ($email == "") {} else {}" and still does the trick same for "if (!$secure) {} if (($secure != $match) .."

- make sure no errors are displayed on your production server if they occur by adding ini_set('display_errors', "0"); to your code instead if an error occurs let it email you with the error report use the directives log_errors and error_log for this

- use if (0 === strcmp($secure, $match)) {/* they are equal */}

- your secure code is of a certain length validate the length

- more to come..

Link to comment
Share on other sites

Sorry the timelimit for editing has passed..

 

- consider using htmlentities() on your input

- i would also use an if on the first and second mail before relocating to success.php, this way you are also able to relocate to failed.php for example

- use a token to make sure they did use the form (when they click the submit button, the token is set)

- reverse your check on "if (($secure!=$match) && ($secure!=""))" if the first failed the second won't even be evaluated

- "if ($email == "") {} if ($email) {}" can easily be written as "if ($email == "") {} else {}" and still does the trick same for "if (!$secure) {} if (($secure != $match) .."

- make sure no errors are displayed on your production server if they occur by adding ini_set('display_errors', "0"); to your code instead if an error occurs let it email you with the error report use the directives log_errors and error_log for this

- use if (0 === strcmp($secure, $match)) {/* they are equal */}

- your secure code is of a certain length validate the length also validate lengths of name and email address (name == a and email address == "a@b.com" are hardly usernames or email addresses)

- use ctype (http://be.php.net/manual/en/ref.ctype.php) to validate that the given input is of a certain type

- more to come..

Link to comment
Share on other sites

First, thanks for the suggestions. Much appreciated! Just a couple of questions on those:

 

- consider using htmlentities() on your input

 

On this one, I looked it up in the php.net manual and apparently all it does is convert certain characters to HTML that have certain HTML qualities. Like HTML special character codes (ex: &#123; or &#x12a; ). I'm assuming that this then prevents them from using certain strings to perform functions or commands by typing them in the url?  (ex: www.mysite.com/form.php?maliciousstuff&morestuff&etc)

 

I'd consider a couple of the suggestions as better coding practices. Thanks for those. I'll check out the ini_set() function to see if that's viable.

 

What about some way of prohibiting them from adding characters to the url? And, would some sort of referrer validation do any good?

Link to comment
Share on other sites

So realistically there's not much I can do except tidy up a bit of the code and add in the filtering and htmlentities() to keep them from using the form for malicious use? We seem to get a lot of 'bounces' lately from these a-holes using various forms or functions on our sites to send out their crap.

 

And just a quick question on the htmlentities() function, would that replace the strip_tags(trim()) setup i'm using now? Or add to it?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.