【问题标题】:How to use php function to report form abuse如何使用php函数举报表单滥用
【发布时间】:2011-03-11 11:26:11
【问题描述】:

我的网站上有一个联系表,一切都像魅力一样。我正在使用反注入验证脚本,我怀疑它应该在有人尝试使用标头注入时发送通知。我已经对此进行了彻底的测试,无法确定为什么它不会在发生滥用事件时通知我。脚本如下。

<?php
/* Set e-mail recipient */
$myemail              = "email@gmail.com";

/* 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@gmail.com";
$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 比较陌生,因此非常感谢任何帮助。

谢谢, 马特

【问题讨论】:

  • 您的主机是否允许您通过 PHP 发送电子邮件?您可以使用 phpinfo() 进行检查。
  • 是的,我可以发送电子邮件,但我无法弄清楚为什么报告注射的部分不会发送。我用评论“开始验证;这就是问题所在”注意到它
  • $report_to = "email@gmail.com";使用单引号或转义 @ $report_to = 'email@gmail.com';或 $report_to = "email\@gmail.com";由于 @ 被视为一个数组,因此它不会在双引号下读取为 email@gmail.com。
  • 谢谢!现在完美运行。
  • 呵呵,有时我们往往会忽略这样的小事......:P很高兴它对你有用。

标签: php forms spam-prevention email-validation code-injection


【解决方案1】:

您的问题可能是您在变量中使用了带有 @ 的双引号: 应该是:$report_to = 'email@gmail.com';$report_to = "email\@gmail.com";

既然你解决了这个问题,就发布我的评论作为答案。

问题是在变量中使用数组而不对其进行转义将导致在您的情况下为空数组,这可能会给您发送错误的电子邮件。

欢迎你:)

【讨论】:

  • ...我对这个答案感到困惑。为什么@会有所作为?直到你的帖子,我相当确定它不是双引号 单引号中的特殊字符,并且测试,我无法找到一种方法来 make 它做出反应任何狡猾的方式。在字符串之外,它是一个错误抑制器,也与数组无关;那么,您可以链接到该信息的来源吗? (将“@”作为搜索关键字非常无效。)我很想知道为什么这样可以解决它。
【解决方案2】:

感谢 Prix 在 cmets 中回答了我的问题:

$report_to = "email@gmail.com";任何一个 使用单引号或转义 @ $report_to = 'email@gmail.com';要么 $report_to = "电子邮件\@gmail.com";自从 @ 被视为一个数组 不读为 email@gmail.com 下 双引号。 – 4 分钟前的大奖赛

【讨论】:

    【解决方案3】:

    我发现了一些可能有助于此的事情。

    1)

    $mail = "$email";
    

    $email 未定义(您在函数内部),并且没有理由在变量周围加上引号。这意味着$mail = "";

    2)

    $headers .= "From: \"".$nama."\" <".$mail.">\r\n\r\n";
    

    你说的是$nama而不是$name,这意味着该行实际上是:

    $headers .= "From:  <>\r\n\r\n";
    

    很难看出原因。尝试在邮件功能之前定义主题和消息(使其更易于阅读)。

    不要使用“@mail”,因为它不会告诉你它遇到的任何错误。调试时,您肯定需要错误消息。

    在发送 HTML 错误(在该函数中)之前尝试发送普通的文本电子邮件,这可能有助于使事情变得简单。然后慢慢实现 HTML,看看哪里坏了。

    【讨论】:

      【解决方案4】:

      下面这几行看起来不对。

      $mail = "$email";应该是 $mail = $email;

      @mail( 应该只是 mail( 这可能是阻止您发送邮件的行!

      mail($myemail, $subject, $message, "From: $email");应该是

      mail($myemail, $subject, $message, "From:".$email);

      希望对您有所帮助。

      【讨论】:

      • @mail 完全有效,只是意味着它不会显示任何警告或错误。 "From: $email" 完全有效。
      猜你喜欢
      • 1970-01-01
      • 2012-09-09
      • 2015-05-19
      • 1970-01-01
      • 2020-11-15
      • 2014-03-17
      • 2013-03-08
      • 2012-10-12
      • 1970-01-01
      相关资源
      最近更新 更多