note 61497 modified in ref.mail by didou
| From: | didou@php.net | Date: | Sun, 23 Apr 2006 22:45:44 +0000 |
| Subject: | note 61497 modified in ref.mail by didou | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-109221@lists.php.net to get a copy of this message | ||
We have finally found the way to stop mail spam, that is beeing sent through unsecure mail forms on
our servers. This is server-wide solution. Of course, this is not ideal solution, but we are hosting
company with hundreds of websites on each server and that's why it is impossible to check them
all. We were looking for a global solution and here it is. There are disadvantages, but it is better
than nothing. Thanks to "appel att nr78 dott net", as I use his function as a base.
This really works and just a few steps required:
1. Put PHP code below to some file (e.g. anti_spam.php) and save it to some place, that is
accessible by all websites. On our servers I place it in /usr/local/lib/php/anti_spam.php
2. In php.ini set these 2 variables:
auto_prepend_file = /usr/local/lib/php/anti_spam.php
safe_mode_include_dir = /usr/local/lib/php
Yes, it will include anti_spam.php in every php file and do check. It could mess some websites, who
are posting these values, but then you can make some workaround for them.
3. The code.
<?php
function _local_replace_bad($value) {
# mail adress(ess) for reports...
$report_to = "anti-spam@yourdomain.com";
# array holding strings to check, we do not trust these strings in $_POST
$suspicious_str = array
(
"content-type:"
,"charset="
,"mime-version:"
,"multipart/mixed"
,"bcc:"
);
$suspect_found = false;
// remove added slashes from $value...
$value = stripslashes($value);
# checks if $value contains $suspect...
foreach($suspicious_str as $suspect) {
if(eregi($suspect, strtolower($value))) {
# if we found some suspicios string, then we add our string, so it
# will be messed a little bit. :)
$suspect_found = true;
$value = eregi_replace($suspect, "(anti-spam-".$suspect.")", $value);
}
}
if ($suspect_found) {
# if at least one suspicios string was found, then do something more
$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'];
# very often HTTP_USER_AGENT is empty. We consider this is 100% spam
if ($suspect_found && $ua == "empty") {
exit();
}
# if we are here, then HTTP_USER_AGENT is not empty. this is only 80-90% that it is spam
# Remember, that POST values were already changed. But we still want to inform our
# admin about this suspicios request.
if(isset($report_to) && !empty($report_to)) {
@mail(
$report_to,
"[ABUSE] [SUSPECT] @ " . $_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-----"
);
} # if report
} # if suscpect found
else { $value = $value_orig;}
return($value);
}
# what we do - is we simply check all posted values.
foreach($_POST as $f=>$v) {
$_POST[$f] = _local_replace_bad($v);
}
# if register_globals is set to "on", then we should overwrite them once again.
if (ini_get("register_globals") == 1)
extract($_POST, EXTR_OVERWRITE);
?>
--was--
We have finally found the way to stop mail spam, that is beeing sent through unsecure mail forms on
our servers. This is server-wide solution. Of course, this is not ideal solution, but we are hosting
company with hundreds of websites on each server and that's why it is impossible to check them
all. We were looking for a global solution and here it is. There are disadvantages, but it is better
than nothing. Thanks to "appel att nr78 dott net", as I use his function as a base.
This really works and just a few steps required:
1. Put PHP code below to some file (e.g. anti_spam.php) and save it to some place, that is
accessible by all websites. On our servers I place it in /usr/local/lib/php/anti_spam.php
2. In php.ini set these 2 variables:
auto_prepend_file = /usr/local/lib/php/anti_spam.php
safe_mode_include_dir = /usr/local/lib/php
Yes, it will include anti_spam.php in every php file and do check. It could mess some websites, who
are posting these values, but then you can make some workaround for them.
3. The code.
<?php
function _local_replace_bad($value) {
# mail adress(ess) for reports...
$report_to = "anti-spam@yourdomain.com";
# array holding strings to check, we do not trust these strings in $_POST
$suspicious_str = array
(
"content-type:"
,"charset="
,"mime-version:"
,"multipart/mixed"
,"bcc:"
);
$suspect_found = false;
// remove added slashes from $value...
$value = stripslashes($value);
# checks if $value contains $suspect...
foreach($suspicious_str as $suspect) {
if(eregi($suspect, strtolower($value))) {
# if we found some suspicios string, then we add our string, so it
# will be messed a little bit. :)
$suspect_found = true;
$value = eregi_replace($suspect, "(anti-spam-".$suspect.")", $value);
}
}
if ($suspect_found) {
# if at least one suspicios string was found, then do something more
$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'];
# very often HTTP_USER_AGENT is empty. We consider this is 100% spam
if ($suspect_found && $ua == "empty") {
exit();
}
# if we are here, then HTTP_USER_AGENT is not empty. this is only 80-90% that it is spam
# Remember, that POST values were already changed. But we still want to inform our
# admin about this suspicios request.
if(isset($report_to) && !empty($report_to)) {
@mail(
$report_to,
"[ABUSE] [SUSPECT] @ " . $_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-----"
);
} # if report
} # if suscpect found
return($value);
}
# what we do - is we simply check all posted values.
foreach($_POST as $f=>$v) {
$_POST[$f] = _local_replace_bad($v);
}
# if register_globals is set to "on", then we should overwrite them once again.
if (ini_get("register_globals") == 1)
extract($_POST, EXTR_OVERWRITE);
?>
http://php.net/manual/en/ref.mail.php