1

I have a contact form that I would like to clean all entries for security reasons.

Following is what I have done so far.

I am using this PHP to start with:

$f_name = cleanupentries($_POST["name"]);
$f_email = cleanupentries($_POST["email"]);
$f_message = cleanupentries($_POST["message"]);
$from_ip = $_SERVER['REMOTE_ADDR'];
$from_browser = $_SERVER['HTTP_USER_AGENT'];

function cleanupentries($entry) {
    $entry = trim($entry);
    $entry = stripslashes($entry);
    $entry = htmlspecialchars($entry);

    return $entry;
}

I am aware of a few issues already, I should escape the user agent so I changed line 4 to: $from_browser = cleanupentries($_SERVER['HTTP_USER_AGENT']);.

Additionally stripslashes() is, from what I understand, no longer needed in later versions due to magic_quotes being deprecated and most recently removed. What should this be replaced with if anything? Should it be left in for reverse compatibility?

I have also heard that newlines might be able to be injected, how can I clean the entries of those?


Here is how everything is being used:

HTML file:

    <form name="ajax-form" id="ajax-form" action="php-file.php" method="post">
        <label for="name">Name: * 
            <span class="error" id="err-name">please enter name</span>
        </label>
        <input name="name" id="name" type="text" />
        <label for="email">E-Mail: * 
            <span class="error" id="err-email">please enter e-mail</span>
            <span class="error" id="err-emailvld">e-mail is not a valid format</span>
        </label>
        <input name="email" id="email" type="text" />
        <label for="message">Message:</label>
        <textarea name="message" id="message"></textarea>
        <button id="send">Submit</button>
        <div class="error" id="err-form">There was a problem validating the form please check!</div>
        <div class="error" id="err-timedout">The connection to the server timed out!</div>
        <div class="error" id="err-state"></div>
    </form>
    <div id="ajaxsuccess"><h2>Successfully sent!!</h2></div>

PHP file (php-file.php):

<?php

$send_to = "contact@example.com";
$send_subject = "Ajax form ";

$f_name = cleanupentries($_POST["name"]);
$f_email = cleanupentries($_POST["email"]);
$f_message = cleanupentries($_POST["message"]);
$from_ip = $_SERVER['REMOTE_ADDR'];
$from_browser = $_SERVER['HTTP_USER_AGENT'];

function cleanupentries($entry) {
    $entry = trim($entry);
    $entry = stripslashes($entry);
    $entry = htmlspecialchars($entry);

    return $entry;
}

$message = "This email was submitted on " . date('m-d-Y') . 
"\n\nName: " . $f_name . 
"\n\nE-Mail: " . $f_email . 
"\n\nMessage: \n" . $f_message . 
"\n\n\nTechnical Details:\n" . $from_ip . "\n" . $from_browser;

$send_subject .= " - {$f_name}";

$headers = "From: " . $f_email . "\r\n" .
    "Reply-To: " . $f_email . "\r\n" .
    "X-Mailer: PHP/" . phpversion();

if (!$f_email) {
    echo "no email";
    exit;
}else if (!$f_name){
    echo "no name";
    exit;
}else{
    if (filter_var($f_email, FILTER_VALIDATE_EMAIL)) {
        mail($send_to, $send_subject, $message, $headers);
        echo "true";
    }else{
        echo "invalid email";
        exit;
    }
}

?>
block14
  • 617
  • 1
  • 8
  • 26

2 Answers2

2

If saving to the database:

Favor prepared statements http://fr2.php.net/pdo.prepared-statements

Or use the PDO Library http://php.net/manual/en/book.pdo.php

But at the very least, use mysqli_real_escape_string(); http://php.net/manual/en/mysqli.real-escape-string.php

EDIT: If you're just emailing the information and not saving it to the database here are a couple functions you can use to properly test data entered for new lines and bad strings that are attempting to do email injection.

/*-----------------------------------------------------------------------
    FUNCTION:   containsBadStr();
    PURPOSE:    Checks for email injection attempts
    ARGUMENTS:  $str_to_test    string, email message, headers, etc.
-----------------------------------------------------------------------*/

function containsBadStr($str_to_test) {
    if (preg_match("/(bcc:|cc:|to:|content-type:|mime-version:|multipart\/mixed|Content-Transfer-Encoding:|http)/i", $str_to_test)) {
        return TRUE;
    } else {
        return FALSE;
    }
}

/*-----------------------------------------------------------------------
    FUNCTION:   containsNewlines();
    PURPOSE:    Checks email message has newlines
    ARGUMENTS:  $str_to_test    string, email address
-----------------------------------------------------------------------*/

function containsNewlines($str_to_test) {
    if (preg_match("/(%0A|%0D|\\n+|\\r+)/i", $str_to_test) != 0) {
        return TRUE;
    } else {
        return FALSE;
    }
}

You'll also want to run strip_tags() to prevent XSS attacks on your form...

Eric
  • 907
  • 7
  • 13
-2

If you are putting these variables in a database all you need to do is use

 mysql_real_escape_string()

So

 $entry = mysql_real_escape_string($entry);

Note you need a database connection open first to use the mysql_real_escape_string function.

Hard worker
  • 3,916
  • 5
  • 44
  • 73
  • 3
    -1 mysql_* functions are deprecated, and the correct way to prevent sql injections is to use prepared statements, not escaping input. – 1615903 Dec 11 '13 at 15:05