question from a "newbie"
I teach a web design class (intro) to hs students.
I am having trouble with a php form processing correctly. The confirmation works, but the form doesn't get sent to the specified email address.
I put the same form on another server and it works properly.
Here is a link to a form that works on the other server, but not linode
Thanks….
18 Replies
global $_POST;
$firstname = $_POST["firstname"] ;
$lastname = $_POST["lastname"];
$emailaddress = $_POST["emailaddress"];
$city = $_POST["city"];
$state = $_POST["state"];
$zip = $_POST["zip"];
$phonenumber = $_POST["phonenumber"];
$where = $_POST["where"];
$message = $_POST["message"];
$to = "
$subject = "Form Submission";
$headers = "From: $emailaddress\n";
$message = "A visitor to your site has filled out the following information.\n
First Name: $firstname
Last Name: $lastname
Email Address: $emailaddress
City: $city
State: $state
Zip: $zip
Phone Number: $phonenumber
Where did you hear about us: $where
Message: $message";
if (pregmatch(' /[\r\n,;\'"]/ ', $POST['emailaddress'])) {
exit('Invalid Email Address');
}
else {
mail($to,$subject,$message,$headers);
}
?>
| **Thank
You.
Your Information Has Been Submitted** |
If it's either Debian or Ubuntu, apt-get install postfix will do the trick.
Don't use a blacklist to detect invalid email addresses and header injection attempts. Use a strict whitelist to pick out the valid ones and toss out the rest!
And are you really sure that you don't need to sanitize any other POST data?
Watch out for non-ASCII characters that you users might submit.
Thanks for your help!
@hybinet:
Security 101
Don't use a blacklist to detect invalid email addresses and header injection attempts. Use a strict whitelist to pick out the valid ones and toss out the rest!
And are you really sure that you don't need to sanitize any other POST data?
Watch out for non-ASCII characters that you users might submit.
I'm sure this is just a basic "here's how to make an email form" type of lesson. There's obviously a lot more code that should go into that to sanitize the variables.:wink:
@Deviation:
I'm sure this is just a basic "here's how to make an email form" type of lesson. There's obviously a lot more code that should go into that to sanitize the variables.
:wink:
Yeah, people take these lessons, then go ahead and implement it on their own websites with a simple copy and paste. You know how HS students love to copy and paste everything! The result is that we have so many millions of insecure websites all over the place. It must done right the first time. By using a blacklist, the code above is giving the students the wrong idea to begin with. And a few of them will go on using the insecure approach for years to come. For all you know, they could end up designing sites that you yourself will later sign up on!
There are some gigantic regexes out there (~4KB) that will sanitize email addresses for you, but 99.9% of all email addresses can be quickly validated using a few simple checks.
99.9% of all email addresses only contain a-z, A-Z, 0-9, hyphen (-), underscore (_), plus (+), dot (.), and at (@). Any other character should raise suspicion, so this should be your basic whitelist.
There should be one and only one at (@) sign in an email address. Any more than one is a sure sign of an attempt to spam multiple people. In addition, the at (@) sign should not be at the beginning or end of the address.
The "domain name" portion of the email address should contain at least one dot. Again, the dot should not be at the beginning or end of the domain name.
The RFC is a lot more complicated of course. All of the following characters can appear in the "local" (username) part of an email address:
! $ & * - = ^ ` | ~ # % ' + / ? _ { }
If you know how to incorporate all of this into a regex, fine. But if you think this is too complicated for your purpose, try to figure out how many people you've ever seen with email addresses that contain a slash or ampersand. It's better to drop a potentially legitimate submission than for your site to be potentially vulnerable. And that's the idea that your students should be getting.
If you're really worried about being too strict, you can use another trick. If an email address is deemed invalid, include it in the body of the message rather than in the From: header. (And stick your own email address instead in the From: header.) You're sending all emails to your own email address anyway, so the worst that can happen is that you'll sometimes have to copy and paste the email address rather than hitting "reply" straight away. This way, you'll also be able to see how many people are trying to hack your code.
As for the other variables, it's a plaintext message so I wouldn't be too paranoid about sanitizing. Some stupid email clients might try to render plaintext messages as HTML and execute scripts in doing so, but I haven't seen such stupid programs recently.
Finally, if you have magic quotes turned on, (it's turned on by default in most distros), PHP will stick a backslash in front of every quote or apostrophe. O'Neill becomes O\'Neill, It's becomes It\'s, and so on. But this is more of a nuisance than a security issue.
@hybinet:
Yeah, people take these lessons, then go ahead and implement it on their own websites with a simple copy and paste. The result is that we have so many millions of insecure websites all over the place. It must done right the first time. By using a blacklist, the code above is giving the students the wrong idea to begin with.
Not going to disagree with you there. As long as the point was made to class about the lack of security in the form code, I wouldn't see an issue. Trying to teach regex in an intro class would be a daunting task.
@Deviation:
Not going to disagree with you there. As long as the point was made to class about the lack of security in the form code, I wouldn't see an issue. Trying to teach regex in an intro class would be a daunting task.
The code posted above already uses a regex to blacklist newlines, semicolons, etc. If so, why not use a rudimentary whitelist instead, such as the following regex?
/^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]+$/
(I do not offer you any guarantee that this regex will work.)
Anyway, I wasn't trying to say that lhswebdesign should teach regex in an intro class, nor that his sample code should be perfectly secure. An intro class is an intro class. As long as the code works and it is reasonably safe to be placed on a web server, no problem. After all, it's going to take quite a bit of effort to defeat lhswebdesign's blacklist.
Rather, my complaint is that the sample code exemplifies a wrong approach to security. Even if the code doesn't get everything done, it must at least point in the right direction. Especially if the code in question is supposed to serve as an example in an educational setting. Blacklisting is inherently insecure, because the bad guys are smarter and more imaginative than you. That's the point that the students are supposed to be getting.
@Xan:
How? The "To" is hardcoded.
The "From" field put in the custom headers isn't, though. If the malicious user or script/program sends a "From" address with a linebreak followed by a CC or BCC field to the script, the script will need to either reject the address completely or at the very least filter out everything beyond the linebreak. If not, the script will essentially be a spam haven (and very quickly put the server and/or local network on a few blacklists).
spearson, did you get any emails from the script prior to being blacklisted on CBL and Spamhaus? The way the script above is set up, it will send you an email for every successful attempt to use it for dark purposes. (Assuming, of course, that you hardcoded your own email address in the To: field.) That should have been a warning that somebody's doing something nasty.
@hybinet:
OMG not already!
:( spearson, did you get any emails from the script prior to being blacklisted on CBL and Spamhaus? The way the script above is set up, it will send you an email for every successful attempt to use it for dark purposes. (Assuming, of course, that you hardcoded your own email address in the To: field.) That should have been a warning that somebody's doing something nasty.
I put the form and script on my server and tested it a couple times with my e-mail address (to recipient) hard coded as was previously stated. It worked and I left the server alone for a few hours forgetting I left it on there. I found out I was blacklisted like 10 hours later when drupal tried to e-mail me and it went to the spam folder. It's probably because the Reply to address was bogus/blank from some tool that screwed around with the form.
Anyways, I got it de-listed from CBL and in-turn Spamhaus so all is good.
@Xan:
Since your email address was hardcoded as the "To" address, wouldn't you have gotten an email for each time the form was used? How many of these did you get?
Unfortunately I wiped my spam folder a few hours ago so I'm not sure.
If someone just kept clicking Submit with no Reply to: address filled out, wouldn't that get Gmails spam detection mad? I'm thinking something like that may have happened.
Is it also possible that Gmail didn't like how the message was formatted ie. just send address and reply to? I personally have no idea ho how headers are properly formatted to avoid being assumed "spam".