0

I've made a PHP contact form for a client and they've come back to me saying they are receiving blank emails like this:

From: 
E-Mail: 
Message: 

I've put JavaScript validation in place which successfully refuses a blank form when I submit the form in the standard way.

  • What could be happening? Are we talking something malicious or stupid?
  • What extra checks should I put in place? Are PHP checks a standard thing?

Code included below. Thanks in advance :)

JS validation:

  $("form#submit").submit(function() {   
    var custname = $('#custname').attr('value');  
    var custemail = $('#custemail').attr('value');  
    var custmessage = $('#custmessage').attr('value');

    if (custname==null || custname=="" || custemail==null || custemail=="" || custmessage==null || custmessage=="") {
      alert("Please fill out the whole form");
      return false;
  }

PHP mailer page:

<?php
$to = "name@email.com";
$subject = "Message from website";
$name_field = htmlspecialchars(trim($_POST['custname']));
$email_field = htmlspecialchars(trim($_POST['custemail']));
$message = htmlspecialchars(trim($_POST['custmessage']));

$body = "From: $name_field\n E-Mail: $email_field\n Message: $message";

mail($to, $subject, $body);
?>
Brian Roach
  • 76,169
  • 12
  • 136
  • 161
KemanoThief
  • 617
  • 8
  • 23
  • 7
    Well maybe people have simply disabled JavaScript. If blanks are not valid, you need to check on the server. You **always** need to check **everything** on the server. – Pointy Nov 13 '11 at 21:12
  • 1
    Also note that you're not trimming spaces in your validation code! – Pointy Nov 13 '11 at 21:13
  • Also note that you've probably got a perfectly lovely brain :-) – Pointy Nov 13 '11 at 21:14
  • What about the HTML - Just because your elements' IDs match those given as keys to the `$_POST` array does not mean that their `name` attributes are identical. Your form elements need to have their `name` attributes match the keys of the `$_POST` array. – nickb Nov 13 '11 at 21:14
  • Are *all* of the messages empty, or is it just a few? – weltraumpirat Nov 13 '11 at 21:15
  • maybe they are calling the action page directly?you should always validate server side – mobius Nov 13 '11 at 21:16
  • Just a few are empty. The page works fine with normal usage - HTML form elements match. Pointy's explanation sounds likely. – KemanoThief Nov 13 '11 at 21:19
  • @Pointy Thanks. My brain is happy with your comment – KemanoThief Nov 13 '11 at 21:21
  • If javascript is the only form validation you have, then you don't have any form validation. Javascript can be turned off, some browsers don't support it (like lynx and other line-mode brosers) and you don't even have to use a browser at all (try connecting to port 80 of any website you like with a simple Telnet client and send a GET / command). Never forget that. – GordonM Nov 13 '11 at 21:39

2 Answers2

2

Any validation occurs on client-side (Javascript) can by bypassed easily, for example by inspecting your page using FireBug.

Validation are used on client-side only for UX (user-experience) to make the user's life easier and faster. So in terms of real validation/security we need to do it again in the server-side (PHP).

In addition this current PHP code is opened to 'E-mail Injection'. You can check this question to make it secure Escape string to use in mail().

In validation/security email stuff, it is better to rely on already well-written/well-tested module such as Pear Mail OR Zend_Mail.

Community
  • 1
  • 1
Laith Shadeed
  • 4,271
  • 2
  • 23
  • 27
1

In the PHP mailer page, you can write something like:-

<?php
// Site Name ( not Site Title )
$dotcom = "Custom Site Name";

$main_mail_arr            = array();
$main_mail_arr['admin']   = 'name@email.com';
$main_mail_arr['noReply'] = 'no-reply@email.com';
$main_mail_arr['cc']      = 'cc@email.com';
$main_mail_arr['bcc']     = 'bcc@email.com';

/**
 * Mail Function
 */
function genMailing($to, $subj, $body, $from = '', $fromName = '', $reply = true, $cc = '', $bcc = '') {
    global $main_mail_arr, $dotcom;

    if( empty( $from ) )
        $from = $main_mail_arr['noReply'];

    if( empty( $fromName ) )
        $fromName = $dotcom;

    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
    $headers .= "From: $fromName <" . $from . ">\r\n";

    if( $reply )
        $headers .= "Reply-to: $fromName <" . $from . ">\r\n";

    if( !empty( $cc ) )
        $headers .= "Cc: " . $cc . "\r\n";

    if( !empty( $bcc ) )
        $headers .= "Bcc: " . $bcc . "\r\n";

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

    $return_str = mail( $to, $subj, $body, $headers );
    return $return_str;
}

/**
 * Email Validation Function
 */
function checkEmail( $email, $type = true ) {
    if(preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i", $email)) {
        $validResult = true;
    }

    if($validResult && $type) {
        $e = explode("@", $email);

        if(@checkdnsrr($e[1])) {
            $validResult = true;
        }
        else {
            $validResult = false;
        }
    }

    return $validResult;
}

if (isset( $_POST['custname'] ) && isset( $_POST['custemail'] ) && isset( $_POST['contact_msg'] )) {
    $nameError = '';
    $emailError = '';
    $msgError = '';

    $valName = trim( $_POST['custname'] );
    $valEmail = trim( $_POST['custemail'] );
    $valMsg = trim( $_POST['custmessage'] );

    if( empty( $valName ) ) {
        $nameError = 'Please provide your Name.';
    }

    if( !empty($valEmail) && !checkEmail($valEmail, false) ) {
        $emailError = 'Please provide your valid Email Address.';
    }

    if( empty( $valMsg ) ) {
        $msgError = 'Please provide your Message / Query / Comments.';
    }

    if( empty( $nameError ) && empty( $emailError ) && empty( $msgError ) ) {
        $to = $main_mail_arr['admin'];
        $subject = "Message from website";

        $body = '<h2 style="padding-bottom:0px; margin-bottom:0px;">New Details</h2>'.'<hr /><br />'."\r\n\n";
        $body .= '<b>Name</b>: '.stripslashes($valName).'<br />'."\n";
        $body .= '<b>Email Address</b>: '.stripslashes($valEmail).'<br />'."\n";
        $body .= '<b>Message</b>: '.stripslashes($valMsg).'<br />'."\n";

        $result = genMailing($to, $subject, $body, $valEmail, $valName, true);

        if ($result) {
            // Message for successful mail sent
        }
    }
    else {
        // Show the form below, with the error messages stored in the error variables
    }
}
?>

This above code mostly covers the server side validation, along with the Email Validation. However, you can also provide more stringent Email Validation checks than the one which I have used, and Captcha checking as well.

Although, the above code has served me well for quite some years, it must be mentioned that this snippet is not the last & full-proof, as I have not used any filter / sanitization (like what WordPress or other CMSs do) for all the user inputs. But nevertheless, it should get you well started with Google when dealing with user inputs.

You can also check out some of the below links for filter / sanitize:-

Hope it helps.

Knowledge Craving
  • 7,955
  • 13
  • 49
  • 92