如何使用php函数举报表单滥用
我的网站上有一个联系表格,一切都很顺利。我正在使用防注入验证脚本,我怀疑该脚本应该在有人尝试使用标头注入时发送通知。我已经对此进行了彻底的测试,但无法确定为什么它不会在发生滥用情况时通知我。脚本如下。
<?php
/* Set e-mail recipient */
$myemail = "[email protected]";
/* Check all form inputs using check_input function */
$subject = check_input($_POST['subject'], "Please enter your name");
$email = check_input($_POST['email'], "Please enter your email");
$form = check_input($_POST['form'], "Please write your message");
function logbad($value)
{
// Start of validation; this is where the problem is
$report_to = "[email protected]";
$name = "Matt";
$mail = "$email";
// replace this with your own get_ip function...
$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'];
$headers = "MIME-Version: 1.0\n";
$headers .= "Content-type: text/plain; charset=iso-8859-1\n";
$headers .= "X-Priority: 1\n";
$headers .= "X-MSMail-Priority: Normal\n";
$headers .= "X-Mailer: php\n";
$headers .= "From: \"".$nama."\" <".$mail.">\r\n\r\n";
@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--"
,$headers
);
}
// Check 1
//First, make sure the form was posted from a browser.
// For basic web-forms, we don't care about anything
// other than requests from a browser:
if(!isset($_SERVER['HTTP_USER_AGENT']))
{
die('Forbidden - You are not authorized to view this page (0)');
exit;
}
// Cek 2
// Make sure the form was indeed POST'ed:
// (requires your html form to use: action="post")
if(!$_SERVER['REQUEST_METHOD'] == "POST")
{
die('Forbidden - You are not authorized to view this page (1)');
exit;
}
// Host names from where the form is authorized
// to be posted from:
$authHosts = array("cover.com");
// Where have we been posted from?
$fromArray = parse_url(strtolower($_SERVER['HTTP_REFERER']));
// Test to see if the $fromArray used www to get here.
$wwwUsed = strpos($fromArray['host'], "www.");
// Make sure the form was posted from an approved host name.
if(!in_array(($wwwUsed === false ? $fromArray['host'] : substr(stristr($fromArray['host'], '.'), 1)), $authHosts))
{
logbad("Form was not posted from an approved host name");
die(' Forbidden - You are not authorized to view this page (2)');
exit;
}
// Attempt to defend against header injections:
$badStrings = array("content-type:",
"mime-version:",
"content-transfer-encoding:",
"multipart/mixed",
"charset=",
"bcc:",
"cc:");
// Loop through each POST'ed value and test if it contains
// one of the $badStrings:
foreach($_POST as $k => $v)
{
foreach($badStrings as $v2)
{
if(strpos(strtolower($v), $v2) !== false)
{
logbad($v);
die('<strong>Form processing cancelled:<br /></strong> string
(`'.$v.'`)<strong> contains text portions that
are potentially harmful to this server. <br />Your input
has not been sent! <br />Please use your browser\'s
`back`-button to return to the previous page and try
rephrasing your input.</strong>');
exit;
}
}
}
// Made it past spammer test, free up some memory
// and continuing the rest of script:
unset($k, $v, $v2, $badStrings, $authHosts, $fromArray, $wwwUsed);
/* If e-mail is not valid show error message */
$addr_spec = '([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c'.
'\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d'.
'\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22)'.
'(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e'.
'\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|'.
'\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c\\x00'.
'-\\x7f)*\\x22))*\\x40([^\\x00-\\x20\\x22\\x28'.
'\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d'.
'\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff'.
']|\\x5c[\\x00-\\x7f])*\\x5d)(\\x2e([^\\x00-\\x20'.
'\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40'.
'\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-'.
'\\x5d\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x5d))*';
if (!preg_match("!^$addr_spec$!", $email))
{
show_error("E-mail address not valid");
}
if (strtolower($_POST['code']) != 'rowingcover') {die('The following error occured: <br />Wrong anti-spam code. <br />
<a href="javascript:history.go(-1)">Go back</a>');}
/* Let's prepare the message for the e-mail */
$message = "Cover.com Contact Form
From:
$subject
$email
Message
$form
";
/* Send the message using mail() function */
mail($myemail, $subject, $message, "From: $email");
/* Redirect visitor to the thank you page */
header('Location: contact_received.html');
exit();
/* Functions we used */
function check_input($data, $problem='')
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
if ($problem && strlen($data) == 0)
{
show_error($problem);
}
return $data;
}
function show_error($myError)
{
?>
<html>
<body>
<b>Please correct the following error:</b><br />
<?php echo $myError; ?><br />
<a href="javascript:history.go(-1)">Go back</a>
</body>
</html>
<?php
exit();
}
?>
我对 php 比较陌生,所以任何帮助将不胜感激。
谢谢, 马特
I have a contact form on my website, and everything works like a charm. I am using a anti-injection validation script, that I suspect is supposed to send a notification when somebody attempts to use header injection. I have tested this thouroghly and cannot determine why it will not notify me on the event of an abuse. The script is below.
<?php
/* Set e-mail recipient */
$myemail = "[email protected]";
/* Check all form inputs using check_input function */
$subject = check_input($_POST['subject'], "Please enter your name");
$email = check_input($_POST['email'], "Please enter your email");
$form = check_input($_POST['form'], "Please write your message");
function logbad($value)
{
// Start of validation; this is where the problem is
$report_to = "[email protected]";
$name = "Matt";
$mail = "$email";
// replace this with your own get_ip function...
$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'];
$headers = "MIME-Version: 1.0\n";
$headers .= "Content-type: text/plain; charset=iso-8859-1\n";
$headers .= "X-Priority: 1\n";
$headers .= "X-MSMail-Priority: Normal\n";
$headers .= "X-Mailer: php\n";
$headers .= "From: \"".$nama."\" <".$mail.">\r\n\r\n";
@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--"
,$headers
);
}
// Check 1
//First, make sure the form was posted from a browser.
// For basic web-forms, we don't care about anything
// other than requests from a browser:
if(!isset($_SERVER['HTTP_USER_AGENT']))
{
die('Forbidden - You are not authorized to view this page (0)');
exit;
}
// Cek 2
// Make sure the form was indeed POST'ed:
// (requires your html form to use: action="post")
if(!$_SERVER['REQUEST_METHOD'] == "POST")
{
die('Forbidden - You are not authorized to view this page (1)');
exit;
}
// Host names from where the form is authorized
// to be posted from:
$authHosts = array("cover.com");
// Where have we been posted from?
$fromArray = parse_url(strtolower($_SERVER['HTTP_REFERER']));
// Test to see if the $fromArray used www to get here.
$wwwUsed = strpos($fromArray['host'], "www.");
// Make sure the form was posted from an approved host name.
if(!in_array(($wwwUsed === false ? $fromArray['host'] : substr(stristr($fromArray['host'], '.'), 1)), $authHosts))
{
logbad("Form was not posted from an approved host name");
die(' Forbidden - You are not authorized to view this page (2)');
exit;
}
// Attempt to defend against header injections:
$badStrings = array("content-type:",
"mime-version:",
"content-transfer-encoding:",
"multipart/mixed",
"charset=",
"bcc:",
"cc:");
// Loop through each POST'ed value and test if it contains
// one of the $badStrings:
foreach($_POST as $k => $v)
{
foreach($badStrings as $v2)
{
if(strpos(strtolower($v), $v2) !== false)
{
logbad($v);
die('<strong>Form processing cancelled:<br /></strong> string
(`'.$v.'`)<strong> contains text portions that
are potentially harmful to this server. <br />Your input
has not been sent! <br />Please use your browser\'s
`back`-button to return to the previous page and try
rephrasing your input.</strong>');
exit;
}
}
}
// Made it past spammer test, free up some memory
// and continuing the rest of script:
unset($k, $v, $v2, $badStrings, $authHosts, $fromArray, $wwwUsed);
/* If e-mail is not valid show error message */
$addr_spec = '([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c'.
'\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d'.
'\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22)'.
'(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e'.
'\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|'.
'\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c\\x00'.
'-\\x7f)*\\x22))*\\x40([^\\x00-\\x20\\x22\\x28'.
'\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d'.
'\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff'.
']|\\x5c[\\x00-\\x7f])*\\x5d)(\\x2e([^\\x00-\\x20'.
'\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40'.
'\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-'.
'\\x5d\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x5d))*';
if (!preg_match("!^$addr_spec$!", $email))
{
show_error("E-mail address not valid");
}
if (strtolower($_POST['code']) != 'rowingcover') {die('The following error occured: <br />Wrong anti-spam code. <br />
<a href="javascript:history.go(-1)">Go back</a>');}
/* Let's prepare the message for the e-mail */
$message = "Cover.com Contact Form
From:
$subject
$email
Message
$form
";
/* Send the message using mail() function */
mail($myemail, $subject, $message, "From: $email");
/* Redirect visitor to the thank you page */
header('Location: contact_received.html');
exit();
/* Functions we used */
function check_input($data, $problem='')
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
if ($problem && strlen($data) == 0)
{
show_error($problem);
}
return $data;
}
function show_error($myError)
{
?>
<html>
<body>
<b>Please correct the following error:</b><br />
<?php echo $myError; ?><br />
<a href="javascript:history.go(-1)">Go back</a>
</body>
</html>
<?php
exit();
}
?>
I am relatively new to php, so any help would be much appreciated.
Thanks,
Matt
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的问题可能是您在变量中使用带 @ 的双引号:
应该是:
$report_to = '[电子邮件受保护]';
或$report_to = "email\@gmail.com";
只是将其作为我评论中的答案发布,因为您已经解决了这个问题。
问题是,在变量中使用数组而不对其进行缩放会导致您的情况出现一个空数组,这可能会给您带来错误的电子邮件。
没关系 :)
Your problem might be that you are using double quotes with @ in your variable:
should be:
$report_to = '[email protected]';
or$report_to = "email\@gmail.com";
Just posting as answer from my comment since you got it solved by that.
The thing was that using an array inside a variable without scaping it will result in a empty array in your case which would give you a possible wrong email.
You welcome :)
我发现了一些可能有助于这一点的事情。
1)
$email 未定义(您位于函数内部),并且没有理由在变量周围加上引号。这意味着
$mail = "";
2)
你说的是
$nama
而不是$name
,这意味着台词实际上是:有点难以看出原因。尝试在邮件功能之前定义主题和消息(使其更易于阅读)。
不要使用“@mail”,因为它不会告诉您它遇到的任何错误。在调试时,您肯定需要错误消息。
尝试在发送 HTML 错误(在该功能中)之前发送普通文本电子邮件,这可能有助于使事情变得简单。然后慢慢实现HTML,看看哪里出了问题。
I have found a few things that might contribute to that.
1)
$email isn't defined (you're inside a function), and there is no reason to put quotes around a variable. This means
$mail = "";
2)
You said
$nama
instead of$name
, this means that line is actually:It's a bit difficult to see the reason. Try defining your subject and message before your mail function (makes it much easier to read).
Don't use the "@mail" as that will NOT tell you any errors it runs into. While debugging, you definitely want error messages.
Try sending a normal text email before you send an HTML error (in that function), it might help make things simple. Then slowly implement HTML, see where it breaks.
以下几行看起来是错误的。
$mail = "$email";应该是 $mail = $email;
@mail( 应该只是 mail( 这可能是阻止您发送邮件的行!
mail($myemail, $subject, $message, "From: $email"); 应该是
mail($myemail, $subject, $message ,“发件人:”。$email);
希望有帮助。
This following lines looks wrong.
$mail = "$email"; should be $mail = $email;
@mail( should be just mail( This is probably the line preventing your mail being sent!
mail($myemail, $subject, $message, "From: $email"); should be
mail($myemail, $subject, $message, "From:".$email);
Hope that helps.
感谢 Prix 在评论中回答了我的问题:
Thanks to Prix who answered my question in the comments: