Has anyone developed a really good defense against email injection attacks?
I'm waging a prolonged campaign against these luser hordes on a number
of non-profit sites I help maintain. I've tried to secure all of the
feedback forms using the function below that I cobbled together from
various php security sites on the web. I also set it up so that every
time a 'successful' attempt is made, it gets logged to a database
before it is emailed.
The script worked well for 2-3 weeks and I enjoyed watching the
spammers bounce off of the firewall. Unfortunately, they finally
figured out how to get through last night and sent out hundreds of
emails on a couple dozen sites. I quickly took all of the forms down
to plug the breach but I can't keep them down indefinitely.
Few questions -
- Does anyone have a better regex to use to detect email injection
attacks? Part of the problem seems to be that they figured out what
values I'm searching for and created a new attack that uses character
references (ex. Y etc) to get through.
- The successful attacks that I logged in my database weren't helpful
because they had already been converted to HTML. Is there a better way
to store _exactly_ what they entered into the field in the database?
- Another way to stop these attacks would be to reject any mail field
over a specified length. Is there a limit to how long an email address
can be? I don't want to set a limit (ex. 50 chars) that excludes
- The most foolproof solution I can think of would be to continue
logging the successful entries to a database and _not_ send the email.
That way even if they get through, no emails get sent. The form would
log the feedback and send an email to the admin that a comment is
available for viewing. Is it time to abandon using mail() for all user
contributed data?
Looking forward to the discussion,
- schnippy
#-----------------------------------------------------------------------
/**
* Secures field against email header injection attacks.
*
* USAGE:
* secureFeedbackValue($_POST["to"]);
* mail($_POST["to"], $_POST["subject"], $_POST["message"]);
*
* @param $value value to be cleansed of evil
*/
function secureFeedbackValue( $value )
{
# mail adress(ess) for reports...
$report_to = "[EMAIL PROTECTED]";
# array holding strings to check...
$suspicious_str = array
(
"\r",
"\n",
"bcc",
"cc:",
"boundary=",
"charset",
"content-disposition",
"content-type",
"content-transfer-encoding",
"errors-to",
"in-reply-to",
"message-id",
"mime-version",
"multipart/mixed",
"multipart/alternative",
"multipart/related",
"reply-to",
"x-mailer",
"x-sender",
"x-uidl"
);
// remove added slashes from $value...
$value = stripslashes($value);
foreach($suspicious_str as $suspect)
{
# checks if $value contains $suspect...
if(eregi($suspect, strtolower($value)))
{
$ip = (empty($_SERVER['REMOTE_ADDR'])) ? 'empty' :
$_SERVER['REMOTE_ADDR'];
$rf = (empty($_SERVER['HTTP_REFERER'])) ? 'empty' :
$_SERVER['HTTP_REFERER'];
$ua = (empty($_SERVER['HTTP_USER_AGENT'])) ? 'empty' :
$_SERVER['HTTP_USER_AGENT'];
$ru = (empty($_SERVER['REQUEST_URI'])) ? 'empty' :
$_SERVER['REQUEST_URI'];
$rm = (empty($_SERVER['REQUEST_METHOD'])) ? 'empty' :
$_SERVER['REQUEST_METHOD'];
if(isset($report_to) && !empty($report_to))
{
@mail
(
$report_to
,"[ABUSE] mailinjection @ " .
$_SERVER['HTTP_HOST'] . " by " . $ip
,"Stopped possible mail-injection @ " .
$_SERVER['HTTP_HOST'] .
" by " . $ip . " (" . date('d/m/Y
H:i:s') . ")\r\n\r\n" .
"*** IP/HOST\r\n" . $ip . "\r\n\r\n" .
"*** USER AGENT\r\n" . $ua . "\r\n\r\n" .
"*** REFERER\r\n" . $rf . "\r\n\r\n" .
"*** REQUEST URI\r\n" . $ru . "\r\n\r\n" .
"*** REQUEST METHOD\r\n" . $rm . "\r\n\r\n" .
"*** SUSPECT\r\n--\r\n" . $value . "\r\n--"
);
}
die ('Snakes on the plane.');
}
}
}
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php