Email script

They have: 7 posts

Joined: Sep 2007

It seems that my new host can't cope with the script I have been using (for the anti-spam bit with image it access another domain on same server) so I am looking for a new script.

Anybody know of a simple free email script that you can add your own fields and with anti-spam security image?

Cheers
Jill

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

Hi Jill,

I posted a simple configurable php email script in my portfolio

You can add and remove fields from the form withoout changing the code

It does not use Captcha - it checks if the mouse is over the submit button - which blocks most bots and automated submissions

you can add Captcha or ReCaptcha if you wish (I am not sure your host will support ReCaptcha, as it communicates with a remote server, but it is pretty popular)

They have: 7 posts

Joined: Sep 2007

Thanks! Have downloaded it and will give it a go.

greg's picture

He has: 1,581 posts

Joined: Nov 2005

Couple of notes about the email script

Why don't you just have the thanks.html in the redir code?

from this

<?php
$ThanksURL
=   "thanks.html";
header("Location: $ThanksURL");
?>

to this

<?php
header
("Location: thanks.html");
?>

Also, you do no sanitisation or checking whatsoever of the user inputs. This leaves it open to potential hacks and spamming attacks. Javascript checks just wont cut it I'm afraid, even kids know how to bypass that.

decibel.places wrote:
It does not use Captcha - it checks if the mouse is over the submit button - which blocks most bots and automated submissions

Most bots and automated spammers don't use the form, they find the page the form is posted to and submits to that. That's the whole point of a captcha, it checks on the following page that the data entered in the form is correct.

And you have no headers set at all for the email. This can cause the email to be listed as junk/spam if it isn't correctly identified.

EG

<?php
$headers
= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";
$headers .= "From: [email protected]\r\n";
$headers .= "X-Mailer: PHP v".phpversion()." \r\n";
?>

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

@Greg,

Thanks for the critique. Smiling

I added the headers and updated the zip download and demo.

The redirect URL is set in the "configure" section, not right above the redirect header as you showed it. There is a bit of code in between that may be confusing to a PHP newbie. I think it is easier for someone new to PHP to set all the custom values together.

Regarding sanitization, what would you recommend? I am kind of naive about that. I am using htmlspecialchars() on the message body to encode html entities.

Regarding the "mouseover" spam protection, it is admittedly not foolproof - but in my experience it reduces spam, without Captcha.

Mollom is another technique to reduce spam, using analysis of the submitted content along with Captcha.

greg's picture

He has: 1,581 posts

Joined: Nov 2005

Sanitisation and checking depends on the form inputs really, but with any user input I always limit them to only typing in what they need to. This helps you get only the data you want from them and limits any potential attacks too.

It's not only about security either, it catches people typing errors or other unwanted data, so allowing you to "direct" them to input the data you want (obviously still with freedom to type their data as required)

I simply run through the posted data for all the fields in the form individually, and if something is not right I send them back to the form with some info as to why they were sent back. The errors are stored in a session, as too are the data they entered.
On the form I output errors and fill in the fields with what they previously typed (if anything).

For example, the name field requires alpha only, more than 1 char and less than 21, so:
(The 'empty', 'letters', 'max' and 'min' are just references so on the form page when they get sent back I know what error to output, you could just store the entire message in the session and echo the relevant session)

<?php
if (strlen($fname) < 1){
$_SESSION['contacterr']['fname']="empty";
$return = "yes";
}elseif (
ereg('[^A-Za-z]', $fname)) {
$_SESSION['contacterr']['fname']="letters";
$return = "yes";
}elseif
(
strlen($fname) > 20){
$_SESSION['contacterr']['fname']="max";
$return = "yes";
}elseif
(
strlen($fname) < 2){
$_SESSION['contacterr']['fname']="min";
$return = "yes";
}
?>

That checks (in order as per code) is string length less than 1 (empty), does the string contain only alpha (a-z), is the string length greater than 20 chars, is it less than 2 chars.

After all the other checks, last name, email address, website if not empty etc, I have this:
(the other checks also set error sessions if checks are true and sets $return to "yes")

<?php
if ($return=="yes"){
$_SESSION['contact']['fname']=$fname;
$_SESSION['contact']['lname']=$lname;
$_SESSION['contact']['website']=$website;
$_SESSION['contact']['email']=$useremail;
$_SESSION['contact']['subject']=$subject;
$_SESSION['contact']['message']=$message;

exit (
header('Location: contact.php'));
}
?>

This sets all the posted data to one session that is echoed out in the form fields when the user is returned with any errors.
Each error info is simply echoed right next to the form input the error relates to using the sessions set (if set) in each check. So from the above example for first name, if the string length from the first name was less than 1, this session will be set:

<?php
$_SESSION
['contacterr']['fname']="empty";
?>

and next to the first name input field on the form it will say "You did not type anything"

On each form input field, I obviously have IF/ELSE to determine if any what errors are to be echoed. There is only ever one echoed for each input field, and will be the most relevant as they are ordered with that in mind in the processing page.

an example is the first name field:

<?php
<label>First Name *</label>
<
input name="fname" type="text" size="20" maxlength="20" class="txtfield" value="<?php echo $_SESSION['contact']['fname']; ? >" />
    <?
php if ($_SESSION['contacterr']['fname']=="letters") {echo "Letters only";}
    elseif (
$_SESSION['contacterr']['fname']=="max") {echo "Max characters is 20";}
    elseif (
$_SESSION['contacterr']['fname']=="min") {echo "Min characters is 2";}
    elseif (
$_SESSION['contacterr']['fname']=="empty") {echo "You did not type anything";}? >
?>

(I've had to put a space on the php end code ? > as otherwise it ends the php code for the forum - Liam ... Sticking out tongue)

I also use the same page the contact form is on to issue a thanks message. If all sanitisation checks are ok and the email is attempted to be sent, it then goes back to the form page with another session set. If on the form page that session is determined as set, it echoes out some of the data they provided (full name and subject).
It also echoes if the email was sent successfully by the server or not, and displays a message accordingly.

The full code can be downloaded here form code
(after stripping out my styling and adding comments) which can be seen as pretty much the same code working at www.worldwide-web.co.uk/contact.php
(this site is being updated so some of it might be a little out of place, but it shows the general idea)
You can submit the form and play with it as much as you want, I'll just ignore any emails that might come through if you enter everything correctly (although, for testing purposes, leaving one of the required fields blank or illegal will not let it send)

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

Greg,

This is a good example of PHP validation (I am using JavaScript as you know) and makes assumptions that I do not want to hard-code into a generic form.

eg. minimum length >= 2, max length >= 20, name alpha only (although these criteria and limits make the input "safer")

Advantage? It will work if JavaScript is not enabled (not many people do that)

Disadvantage? It requires PHP processing on the form, which means either making the form a PHP file or enabling PHP in HTML (not for beginners), and some more advanced PHP coding than the basic form I created. Remember, this was developed for someone who knows little about PHP.

This is designed to be a simple form someone can drop into an HTML page, set a few configurations in the PHP file and create a thanks page or use the default with the redirect...

I have used PHP for form validation many times, but that is not required or desired here.

I asked about "sanitization" and preventing malicious code - if htmlspecialcharacters() is not sufficient Confused

greg's picture

He has: 1,581 posts

Joined: Nov 2005

decibel.places wrote:
I am using JavaScript as you know
Which is only safe and decent for honest visitors. bots/spammers/hackers bypass that in seconds.

decibel.places wrote:
Disadvantage? It requires PHP processing on the form, which means either making the form a PHP file or enabling PHP in HTML (not for beginners), and some more advanced PHP coding than the basic form I created. Remember, this was developed for someone who knows little about PHP.
Then there is no alternative to making it safe and ensuring visitors only type what they should. If a person doesn't know or doesn't want to learn PHP/ASP (etc) then there is going to be no serious security or integrity checking.

The options are - 1) Learn PHP and the security measures as in my code 2) Get or pay someone else to do it 3)Don't have any serious security checking

decibel.places wrote:
I have used PHP for form validation many times, but that is not required or desired here.
I would have to disagree. Any/all user input that is parsed by PHP on a server should be checked for the minimum. Including if it's sending out an email, and email injection is something that should be safe guarded against.

decibel.places wrote:
I asked about "sanitization" and preventing malicious code - if htmlspecialcharacters() is not sufficient :?
htmlspecialchars will only translate the following
'&' (ampersand) becomes '&amp;'
'"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set.
''' (single quote) becomes '&#039;' only when ENT_QUOTES is set.
'<' (less than) becomes '&lt;'
'>' (greater than) becomes '&gt;'

and NOTHING else.

That leaves it open to spam attacks. That is, if someone attempts to modify your headers they send their company spam out to every man and his dog through your server by using CC or BCC.
Ok, it can be argued that this is very unlikely to happen, and I agree with that, but that doesn't stop the need for security.
It's more likely a car thief will break a window without even trying the doors. Do you leave your car unlocked due to this?

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

greg wrote:
That leaves it open to spam attacks. That is, if someone attempts to modify your headers they send their company spam out to every man and his dog through your server by using CC or BCC.

That is why I am setting the headers in the processing script, right?

And htmlspecialcharacters() will defang most email injection malicious code, without < > and quotes (yes, ENT_QUOTES is set) - what other processing would you recommend apart from limiting the input?

Remember, this is intended to be a simple form someone with little or less PHP experience can add for simple email contact.

Sure, the site owner can learn PHP or hire someone - but what if they just want a simple DIY (as in the OP - there was a problem with captcha, I offered a solution that is perhaps not as spam-proof but works "pretty well").

I am using "mouseover" detection on some forms on my old site at GeoCities Free Hosting, where PHP is not available. Formerly I got about 20-30 spams a day, now I get about 1 per day (and that one could be a human submission).

Although limiting the input equals some greater security, I do not think it is necessary IN THIS SITUATION, and IN THIS SITUATION I do not want to force the doc with the form to process any PHP (meaning the owner would need to convert the page with the form to a PHP file, which would require adjustments to navigation - or play around with .htaccess for PHP processing in HTML files if it isn't already enabled).

Different tools for different situations-

You don't need to use a backhoe when a hand spade will do...

greg's picture

He has: 1,581 posts

Joined: Nov 2005

decibel.places wrote:
That is why I am setting the headers in the processing script, right?
No, that's to stop recipient mail servers determining that your email is spammy. This is especially required on shared hosting.
Ok, so if the mail is just going to your inbox then it's arguably not an issue, but it's not good practice either, and you don't want to be trawling through your spam box/junk for customers/site visitors emails.

decibel.places wrote:
And htmlspecialcharacters() will defang most email injection malicious code, without < > and quotes (yes, ENT_QUOTES is set)

It will certainly help yes, but it's not fool proof.
Although it will catch a lot of hack attempts and possibly spam, it doesn't STOP them, the email will still be sent to the site owners inbox (or 50,000 other people's inboxes too)
And, to note, in your code you actually set ENT_NOQUOTES, you might want to change that as then you are removing the only and vital part of security that htmlspecialchars provides.
And of course with running the entire form data through htmlspecialchars you make the email that the site owner receives a little messy. Some may not be bothered, but it wont be good if the site owner tries to add the visitor into the recipient list to get a copy as well.

In all it's "ok", but it's not really an efficient or reliably safe method to stop spam injection, nor is it a tidy method for the email content.

decibel.places wrote:
what other processing would you recommend apart from limiting the input?
Well, there isn't anything you can do really. You can check the users entered email MX DNS records and validity, but that's perhaps defined as limiting user inputs. Other than limiting user inputs to characters they should only be using, like numerical only on date of birth (etc) there really is no other "decent" methods I know of...maybe someone else can add some comments/ideas on this as it seems to be only me and you bashing it out Sticking out tongue

decibel.places wrote:
Remember, this is intended to be a simple form someone with little or less PHP experience can add for simple email contact.
Some things just cannot be simplified, at least not without some compromise somewhere.
I know you are trying to create a simple code for people who don't code in PHP, but even the most simplest code, like the one you created, is going to be bewildering to non php coders.

So if they don't understand <?php?> and things like you have in their script, then there is nothing gained by leaving out other checks.

You have this in your code:

foreach ($_POST as $Field=>$Value)
$MsgBody .= "$Field: $Value\n";
$MsgBody .= "\n" . @gethostbyaddr($_SERVER["REMOTE_ADDR"]) . "\n" .
$_SERVER["HTTP_USER_AGENT"];
$MsgBody = htmlspecialchars($MsgBody, ENT_NOQUOTES);  //make safe

That's not going to be understood by someone who doesn't code PHP as much as the stuff I have in mine.
Although I know my method requires specific inputs, whereas yours allows for universal, but coding a universal one with the provision of user inputs isn't impossible, you would just have to use a check for post data rather than specific posted form input names.

decibel.places wrote:
Sure, the site owner can learn PHP or hire someone - but what if they just want a simple DIY (as in the OP - there was a problem with captcha, I offered a solution that is perhaps not as spam-proof but works "pretty well").
Then what you already offer is fine, but comes without any major security checking or integrity checks.
All the checks my script has can be argued to be over the top in terms of security requirements, but it makes sure its secure, the user only types what they should and that also helps in preventing spam, as bots will get sent back to the form with errors.

decibel.places wrote:
I am using "mouseover" detection on some forms on my old site at GeoCities Free Hosting, where PHP is not available. Formerly I got about 20-30 spams a day, now I get about 1 per day (and that one could be a human submission).
If you did absolutely no other changes at all (stop advertising on some sites, remove form sigs etc etc) then you obviously resolved some issues with it. But it's by no means proof of any kind that you made it fool proof, you just stopped the spam type you were getting, as I said, bots usually bypass the form anyway, so the javascript mouse hover over detection woulnd't even come into the equation.

decibel.places wrote:
Although limiting the input equals some greater security, I do not think it is necessary IN THIS SITUATION, and IN THIS SITUATION I do not want to force the doc with the form to process any PHP
Then don't. It being necessary is obviously opinion based on tight security and integrity versus easy to use.
There are compromises with everything in life, and the compromise with easy to code form scripts are they are not as secure.

Cheap house window locks are much less secure than decent ones for a bit more money, but if you can only afford the cheap ones, then that's the compromise you should be willing to take.
They are better than no window locks, as with the htmlspecialchars is better than nothing, and both the window locks and using htmlspecialchars could be argued to be sufficient, but that depends on the attacker/burglar.

decibel.places wrote:
You don't need to use a backhoe when a hand spade will do...
True, unless you DO need a backhoe and you mistakenly think you only need a hand spade.

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

greg,

I think we have come to some agreements here (we weren't actually arguing, after all, just cordially debating pros and cons)

I hope this thread will be helpful to someone balancing the need for security with simplicity of use.

Commonly in programming we make choices, I usually try to follow the LOGIC of the project to determine how to implement the solutions.

True, unless you DO need a backhoe and you mistakenly think you only need a hand spade.

How true... Smiling

greg's picture

He has: 1,581 posts

Joined: Nov 2005

decibel.places wrote:
I think we have come to some agreements here (we weren't actually arguing, after all, just cordially debating pros and cons)
Of course.
Our discussion will hopefully provide info for the OP and anyone else reading.

I still maintain the simple conclusion for your particular circumstance is compromise, and may well be what babrees will have to do too.

It still always comes down to the three choices, do it yourself even if it means learning PHP, get someone else to do it even if paid or don't have the highest possible security and integrity checks.

He has: 629 posts

Joined: May 2007

I'm a bit late here, but if a contact form is what you are after, you could do a lot worse than Mike Cherim's Secure and Accessible PHP Contact Form.

Cordially, David
--
delete from internet where user_agent="MSIE" and version < 8;

Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.