Page 1 of 1

Need help with my script's security

Posted: Thu Aug 02, 2007 5:31 am
by arukomp
Some time ago I almost lost my hosting account for "sending spam". I had to remove my Contact Us page to ensure this doesn't happen again. But my site isn't so good without any support to people visiting my site. So a few days I've been reading some security articles and have coded a new version of my Contact Us page. Here it is:

Code: Select all

<?php

require("config.php");

if ($_POST['action'] == "send") {
	if (strtolower($_SERVER['HTTP_REFERER']) != strtolower("$url/support.php") && strtolower($_SERVER['HTTP_REFERER']) != strtolower("$url2/support.php")) {
		echo "Error: An unsuspected error has occured.<br>";
		$error = true;
	}
	if (strlen($_POST['name']) > 20) {
		echo "Error: Name is too long. 20 characters max.<br>";
		$error = true;
	}
	if (strlen($_POST['email']) < 40) {
		echo "Error: E-mail address is too long. 40 characters max.<br>";
		$error = true;
	}
	$email_pattern = '/^[^@\s<&>]+@([-a-z0-9]+\.)+[a-z]{2,}$/i';
	if (!preg_match($email_pattern, $_POST['email'])) {
		echo "Error: E-mail address is not valid.<br>";
		$error = true;
	}
	if (!$error) {
		$name = htmlspecialchars(strip_tags($_POST['name']), ENT_QUOTES);
		$email = strip_tags($_POST['email']);
		$message = htmlspecialchars(strip_tags($_POST['message']), ENT_QUOTES);
		$mail = mail($e_mail, "$pname Support Request", $message, "FROM: $email");
		if ($mail) {
			echo "<font color='green'><b>Your message has been successfuly sent. Thank You.</b></font><br><br>";
		}
		else {
			echo "<font color='red'><b>There has been an error. Please send your message to <a href='mailto:$e_mail'>$e_mail</a>. Thank You.</b></font><br><br>";
		}
		$sent = true;
	}
	echo "<br>";
}

if (!$sent) {
?>
<form action="contact.php" method="post">
<input type="hidden" name="action" value="send" />
Name:<br>
<input type="text" name="name" maxlength="20"><br><br>
Your E-mail address:<br>
<input type="text" name="email" maxlength="40"><br><br>
Message:<br>
<textarea name="message" rows="6" cols="30"></textarea><br><br>
<input type="submit" name="submit" value="Send">
</form>
Some information:
$url and $url2 are same url's but one with www and one without www, in case user would be browsing my site with www in it or without it.

The question is, is this script secure? Can I put it on my host without any risk to loose it? Also, does it change anything if hacker gets the code? I'll be sharing my site script with other people who also want to have site like mine, so I don't know if one of those people might hack into my site and make me loose my hosting.

Thanks

Re: Need help with my script's security

Posted: Thu Aug 02, 2007 6:29 am
by timvw
The question is, is this script secure?
No it's not secure.

- You're not verifying if the variables exist (eg: $POST['name'])
- What are you trying to achieve with checking a HTTP_REFERER header? It's not even a required one.. So any user-agent that doesn't provides it, would have difficulty using your site.
- Why would an e-mail address be limited to 40 characters?
- Your 'filtering' still doesn't remove newlines and thus allows for header injection.

The easiest way to create a 'safe' e-mail form is (imho) by hardcoding the recipient and all the headers... This way an attacker can try to abuse your via the mail body..

Posted: Thu Aug 02, 2007 10:14 am
by arukomp
Thanks for the tips. Well, "hardcoding" doesn't sound so easy :?

I limit e-mail address to 40 characters to ensure attacker doesn't input a list of e-mails addresses.

I'm still new to security, maybe there's any good freeware contact script which I could use and also learn from it? It would be great. Or maybe some article about filtering data or anything else related to that?

Thanks

Posted: Thu Aug 02, 2007 6:44 pm
by timvw
You could start with a websearc, i used: 'php e-mail injection'.. And found (eg) http://www.securephpwiki.com/index.php/Email_Injection

Posted: Thu Aug 02, 2007 7:08 pm
by Benjamin
arukomp wrote:I limit e-mail address to 40 characters to ensure attacker doesn't input a list of e-mails addresses.
You should validate the email address instead using regex.

Posted: Thu Aug 02, 2007 10:37 pm
by shiflett
The major weakness in your code is that you fail to filter $email.

Most spammers aren't going to try to exploit you by adding a large list of email addresses to the To header. (You still want to make sure that's not a possibility, of course.) That's too obvious, so they typically try to inject multiple Bcc headers in their email address, expecting that you'll use it exactly as you have. This lets them send spam to a very large list of recipients, and you're far less likely to notice, because you won't see the list in the email you receive. (You'd have to notice network traffic anomalies or something similar.)

There are two useful things you can do with $email:

1. Filter it using Cal Henderson's pattern: http://iamcal.com/publish/articles/php/parsing_email/
2. As defense in depth, use ctype_print() to ensure all of the characters are printable. (Newlines and carriage returns aren't.)

Hope that helps.