473,395 Members | 1,763 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Is this a secure PHP mail form?

uranuskid
Hey folks,

I was going to include a contact form on my website. Well, in the first place that seemed an easy thing to do with a form that prompts a PHP file validating the input vaiables and using it's mail () function to send the mail. However, as I got more into that topic I realized that one should be really concerned about the validation part to prevent spam abuse.

There are shiploads of 'mail scripts' available with each of them has it's pros and cons as widely discussed and even argued in various forums (e.g. an example on thescripts.com: http://www.thescripts.com/forum/thread640302-mail+form.html). With all that controversion about the mailform security issues I thought I'd start a forum thread that may help to understand relevant variable validation in a PHP driven contact mail form.

As an example I like to discuss the 'php from mailer' availabe on www.thedemosite.co.uk. It employs two files, an html file with the form including brief javascript validation for input data and as a second file php driven variable validation to prevent spam abuse through header injection.

The form and javascript validation part looks like this:
[HTML]
<form name="phpformmailer" action="contact.php" align="center" method="post">
<div align="center"><table>
<tr>
<td>Your name:</td>
<td ><input type="text" size="29" name="name"></td>
</tr>
<tr>
<td>* Your email address:</td>
<td ><input type="text" size="29"
name="email"></font></td>
</tr>
<tr align="middle">
<td>* Confirm email address:</td>
<td ><input type="text" size="29" name="email2"></td>
</tr>
<tr>
<td >* Subject:</td>
<td ><input type="text" size="29" name="thesubject"></td>
</tr>
<tr>
<td >&nbsp;<p>* Your request or query:</td>
<td ><textarea style="FONT-SIZE: 10pt" name="themessage" rows="7" cols="27"></textarea></td>
</tr>
<tr>
<td ></td>
<td ><script language="JavaScript"><!--
function validateForm()
{
var okSoFar=true
with (document.phpformmailer)
{
var foundAt = email.value.indexOf("@",0)
if (foundAt < 1 && okSoFar)
{
okSoFar = false
alert ("Please enter a valid email address.")
email.focus()
}
var e1 = email.value
var e2 = email2.value
if (!(e1==e2) && okSoFar)
{
okSoFar = false
alert ("Email addresses you entered do not match. Please re-enter.")
email.focus()
}
if (thesubject.value=="" && okSoFar)
{
okSoFar=false
alert("Please enter the subject.")
thesubject.focus()
}
if (themessage.value=="" && okSoFar)
{
okSoFar=false
alert("Please enter the details for your enquiry.")
themessage.focus()
}
if (okSoFar==true) submit();
}
}
// --></script><input type="button" value="Send" name="B1" ONCLICK="javascript:validateForm()">
You must fill in the fields marked with a *</td>
</tr>
</table>
</div>
</form>
[/HTML]

OK so far, I quite like the idea of checking whether all required fields are filled up with that little javascript function. At first check whether there is an email address with the variable 'foundAt'. Well, actually one might like to use even more validation and check the email address for accuracy using something like that instead:

var goodemail = email.value.match('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.
'@'.
'[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
'[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$')

if (goodemail == 1 && okSoFar) ...

So what's your impression 'bout that. Is it useful to check email address accuracy in detail, as we do not have any concern about any database issues? Anyway, it might be good thing to do. The remaining javascript code is selfevident.

Now the PHP code in the calling file that checks for spam abuse. It starts with three variables later on used to see whether the file was actually prompted from your website.
[PHP]
$valid_ref1="http://Your--domain/contact.html";
$valid_ref2="http://www.Your--domain/contact.html";
$replyemail="YOU@Your--domain";
[/PHP]

Then a function is defined validating header injection:
[PHP]
function clean_input_4email($value, $check_all_patterns = true)
{
$patterns[0] = '/content-type:/';
$patterns[1] = '/to:/';
$patterns[2] = '/cc:/';
$patterns[3] = '/bcc:/';
if ($check_all_patterns)
{
$patterns[4] = '/\r/';
$patterns[5] = '/\n/';
$patterns[6] = '/%0a/';
$patterns[7] = '/%0d/';
}
//NOTE: can use str_ireplace as this is case insensitive but only available on PHP version 5.0.
return preg_replace($patterns, "", strtolower($value));
}

$name = clean_input_4email($_POST["name"]);
$email = clean_input_4email($_POST["email"]);
$thesubject = clean_input_4email($_POST["thesubject"]);
$themessage = clean_input_4email($_POST["themessage"], false);

$error_msg='ERROR - not sent. Try again.';
[/PHP]
A confirmation text is outputed and a confirmation mail is send to the author of the message when the input passes this test and another one further down.
[PHP]
$success_sent_msg=' some message'

$replymessage='some message'
[/PHP]
Now the biscuits, what we wanted to do in the first place - send an email to the domain admin, support, CRM or what ever through the from. Again the PHP code checks for the email field to be set (see below) and if the form was actually submitted from your domain (here now are the three variables from the start kickin' in. If the referrer don't match you'll be asked to sent the form again, from the right site. If that's all right the mail to you and the inquiring person are sent and the webuser gets an message that verything was fine

[PHP]
if (!isset($_POST['email']))
{
echo "<script language=\"JavaScript\"><!--\n ";
echo "top.location.href = \"$valid_ref1\"; \n// --></script>";
exit;
}

$ref_page=$_SERVER["HTTP_REFERER"];
$valid_referrer=0;
if($ref_page==$valid_ref1) $valid_referrer=1;
elseif($ref_page==$valid_ref2) $valid_referrer=1;
if(!$valid_referrer)
{
echo "<script language=\"JavaScript\"><!--\n alert(\"$error_msg\");\n";
echo "top.location.href = \"$valid_ref1\"; \n// --></script>";
exit;
}
$themessage = "name: $name \nQuery: $themessage";
mail("$replyemail",
"$thesubject",
"$themessage",
"From: $email\nReply-To: $email");
mail("$email",
"Receipt: $thesubject",
"$replymessage",
"From: $replyemail\nReply-To: $replyemail");
echo $success_sent_msg;
[/PHP]

That's an awful lot of code to be posted here, but in comparison with other scipts it is actually quite few. To my rudimentary undestanding of programming and internet security I would assess it as: IT DOES THE JOB. But if I was without concern I wouldn't start a thread here and therefore 'd like to hear some of the advanced voices here on this php mailform.

Cheers,
Frank
May 15 '07 #1
3 3264
code green
1,726 Expert 1GB
OK so far, I quite like the idea of checking whether all required fields are filled up with that little javascript function
Ok if the client machine has javascript enabled.
A confirmation text is outputed and a confirmation mail is send to the author of the message
I also send an encrypted code within a hyperlink, with a polite explanation asking the sender to confirm by clicking the link. This at least confirms you are dealing with a genuine address and a genuine (but slightly annoyed) customer.
If the referrer don't match you'll be asked to sent the form again, from the right site
For the determined this can be bypassed with a bogus form. [HTML]var goodemail = email.value.match('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.
'@'.
'[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
'[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$')

if (goodemail == 1 && okSoFar) ...[/HTML]
Email pattern matches always mean you will upset somebody with an obscure address. I was turning away (unknowingly) Gaelic names for about 3 months. The header injection is useful but what about SQL injection? It looks OK. Don't like the reliance on javascript.
May 15 '07 #2
pbmods
5,821 Expert 4TB
For an in-depth explanation of email-address validation, check out this article:
http://www.quirksmode.org/js/mailcheck.html

There's also a decent article here (the site has a really nice reference section):
http://www.regular-expressions.info/email.html
May 16 '07 #3
To code green,

Well, I gues you prefere validating form input in the PHP file, right?

So something like that would work even if the client hasn't got javascript enabled:

[PHP]

if (empty($_POST['fieldname'])
{ print "<p> Please enter coorect .... </p>":
print "<a href=\"javascript:history.back()\">Back</a>"; }
[/PHP]
But then you'd need javascript anyway to go back or you do it all in one file but wouldn't you expose your email address to the public then?

Also, why would you suggest to check for SQL injection? I mean there is no connection to database in the files. Wouldn"t it just extent the script length in vain to check 4 SQL injection?

To pbmods,

Thanks for the link to the javascript email check. It seems a lot easier than my version which does the job however, too. But, that was not really an impression whether the whole thing would pass your assessment as secure mailform, right!!

Regards

Frank
May 16 '07 #4

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: Alexander Ross | last post by:
I am trying to create a simple mail form (i.e. five fields, the users pushes send and using the mail function I get an email with their input values). The problem is that some people will be...
2
by: Joker | last post by:
Hello, I'm trying to make a mail-form with PHP. But the point is I want a function so the user can choose the receiver (adress) with a drop-down menu box. example:...
2
by: Andre | last post by:
I'm trying to add a asp.net page which will act as a contact-me e-mail form to keep our e-mail addresses hidden from page visitors. I've created a combo/drop down box listing our various...
1
by: dajar | last post by:
I'm trying to install a simple e-mail form to my webpage; which takes some info from user (like name, phone, e-mail,etc...) and when user pushes submit button e-mails them to me immediately. I've...
0
by: spyyder | last post by:
ANY HELP would be really really appreciated dudes.. Ok.... heres the snag...my flash mail form has these fields, TextInputs: 'name' , 'email', 'budget', TextAreas: 'Message' ComboBoxes:...
1
by: IcarusZulu | last post by:
Hi all I have a mail form on my website. 99% of the time it works fine however sometimes it dose not. Whats happening is when a customer hits submit the content data is lost. I think it has...
5
by: Henry Stock | last post by:
My ISP provides this sample for an ASP.NET capable email form. If you have any idea about how to do the following, I would greatly appreciate your help. I have a few alterations that I would...
8
by: blaqpig | last post by:
Hey all I keep trying to copy a php mail form that I found on the internet, but everytime I insert it into my HTML file it doesnt acknowledge it like it did when it was originally saved as a .php...
5
by: wktarin | last post by:
Hi. I'm a relative newcomer to the world of php, and I keep bumping into a problem with a mail () form. I need to send an automatic email to two addresses, but I can't seem to get it to work. One...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.