View Full Version : wrinting a secure php formmail?
Hi
I would like a php formmail on my site and was considering using some code like this:
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$strippetName = strip_tags($name);
$strippetEmail = strip_tags($email);
$strippetMessage = strip_tags($message);
PRINT "<CENTER>";
PRINT "Hi, $strippetName .";
PRINT "<BR><BR>";
PRINT "Thanks for your message.<BR><BR>";
PRINT "</CENTER>";
mail("my@emailaddress",
"sitename",
"Username: $strippetName
User email addresse er $strippetEmail.
Message: $strippetMessage.", "From: $strippetEmail\r\n");
But I have heard a lot about formmail exploits where they are used to send SPAM.
As I would not like that I would like to know what I can do to my little script to make it tamper resistent.
Martin
Burhan 11-28-2005, 07:11 AM What happens to your script if someone enters CC: me@mydomain.com as their email address? :)
Well, that would be one of the problems I can see but how do I avoid it?
-Edward- 11-28-2005, 09:33 AM Use if statement to block it:
if (!CC:) {
echo "Sorry you can't send using Carbon Copy";
}
Or something along those lines ....
realwebsolution 11-28-2005, 12:04 PM You need also add flood control to your function.
malenski 11-28-2005, 02:01 PM I believe most hacks of the php mail() function are done by injecting header information.
Your not validating the POST'd data.
$email = $_POST['email']; -> $strippetEmail = strip_tags; -> then its used in mail()
No where is $email checked to see if its a valid email address. You don't even have to make sure its a account that can recieve email. You should make sure it is a valid format (ie NO escape characters like \r\n)
1 - Validate data
2 - Error if needed
4 - if all is good use mail()
This is the same kind of algo I use at my site (malenski.com/contact.php).
Good source of info : http://securephp.damonkohler.com/index.php/Email_Injection
bertus144 12-09-2005, 09:25 PM I'm using a simple form that sends me an e-mail with the information entered, on my site. And now I'm wondering whether I'm at risk because the only fields that are filled are the to: (my own address, hard-coded), subject (hard-coded) and message (all the entered information in succession). I do not fill any header information. I'm assuming I'm not at risk this way?
Thanks,
Bertus
Azavia 12-09-2005, 09:46 PM I agree you should do input validation.
To malenski:
How can one enter a linebreak if it is a normal text input field? I was trying to test this, and I was able to enter 0X0A (\r), but not 0X0D (\n), which is generally needed to make a true newline. When I tried entering the character 0X0D it simply submitted the form.
camers 12-09-2005, 09:53 PM I'm using a simple form that sends me an e-mail with the information entered, on my site. And now I'm wondering whether I'm at risk because the only fields that are filled are the to: (my own address, hard-coded), subject (hard-coded) and message (all the entered information in succession). I do not fill any header information. I'm assuming I'm not at risk this way?
Thanks,
Bertus
I would assume if the information was not a variable then it couldnt be altered. So then I'd think it wouldnt be at risk. But not too sure..
orbitz 12-09-2005, 10:06 PM make sure the email is valid - checking all the chars.
hiryuu 12-09-2005, 11:10 PM How can one enter a linebreak if it is a normal text input field? I was trying to test this, and I was able to enter 0X0A (\r), but not 0X0D (\n), which is generally needed to make a true newline. When I tried entering the character 0X0D it simply submitted the form.
You're not going to use the form to send hundreds/thousands of messages. You're going to use a script to build the POST data directly and send it to the form's destination. Alternatively, you could make a form with a textarea that submits to the same destination. Length limits, drop-down menus, and Javascript are there for the convenience of the user, but at no point should your script depend on those boundaries or expect the client end to enforce them.
Azavia 12-09-2005, 11:20 PM You're not going to use the form to send hundreds/thousands of messages. You're going to use a script to build the POST data directly and send it to the form's destination. Alternatively, you could make a form with a textarea that submits to the same destination. Length limits, drop-down menus, and Javascript are there for the convenience of the user, but at no point should your script depend on those boundaries or expect the client end to enforce them.
Oh, I see what you mean. I should of thought of that. :)
Thanks for the reply.
bertus144 12-10-2005, 07:05 AM I would assume if the information was not a variable then it couldnt be altered. So then I'd think it wouldnt be at risk. But not too sure..
Well, the only part that's variable is the message, no harm can be done there, right?
tmesolutions 12-10-2005, 02:51 PM never let the user have access to add anything in the headers simple as that.
Dont set the from header to the email address they entered. No1, its not accurate.. and No2 its an open door to exploits. spammers will post an email address of something like: me@me.com \nto:spam@somone.com etc
set the from address to something like webform@yoursite.com
malenski 12-10-2005, 08:28 PM I agree you should do input validation.
To malenski:
How can one enter a linebreak if it is a normal text input field? I was trying to test this, and I was able to enter 0X0A (\r), but not 0X0D (\n), which is generally needed to make a true newline. When I tried entering the character 0X0D it simply submitted the form.
This page details how to inject headers if its a normail input field. Which by the way it doesn't have to be, through cross site scripting I can post any form and any data to the same form his script posts to.
http://securephp.damonkohler.com/index.php/Email_Injection
camers 12-10-2005, 08:34 PM How would you log each email sent via the script? Just curious about setting this up.
nnormal 12-13-2005, 12:44 PM ok - this post got me paranoid.
is it possible to get an exploit through something like this?
<html>
<form method="post">
<input type="text" name="sender">
<input type="submit" value="go">
</form>
<?
if (isset($_POST['sender'])) {
if (!preg_match('/^(\w+)(@)(\w+)(\.)(\w+)$/',$_POST['sender'])) {
?>
<script>
alert('bad');
</script>
<?
}
else {
$sender = trim($_POST['sender']);
$sender = stripslashes($sender);
$mailheaders = "From: $sender\nReply-To: $sender\n";
}
}
?>
</html>
tmesolutions 12-13-2005, 12:52 PM your script is fine.. to check add the following line at the top of the php (i did and it worked)
$_POST['sender'] = "dsfdsfg@dsfgdg.com\nto: spam@spam.spam";
|