我在一个文件中有以下代码,当变量$action
等于某个值时,会向数据库添加一条消息,然后向用户发送一封电子邮件,通知他们该消息。简单。
在过去几天中,数据库中添加了垃圾邮件,并向用户发送了电子邮件,通知他们有新邮件。不是很多而不是一次全部,只是随机时间和内容,但显然是垃圾邮件。
我设置脚本,以便如果$from
变量不等于0,那么就不要继续,但它似乎以某种方式绕过了(所有黑客条目进入db show from_userid = 0
)
我正在使用Cookie来检查用户是否已登录 - 当用户登录cookie时已设置。
问题:有什么地方我可以看看我是如何被黑客攻击的,如果我使用的是会话而不是cookie,会阻止文件被访问/攻击吗?
下面是代码:
// check a user logged in as soon as file accessed
if (!isset($_COOKIE['cookieName'])) { header("Location: /userlogin.html); }
现在检查$action
变量并继续
$action = $_POST['action'];
if (($action=='contact') && ($_POST['from'])){ // AA
require_once '/home/php/lib/setup.inc';
require_once '/home/php/lib/dbconnect.inc';
$from = mysql_real_escape_string($_POST['from']);
$to = mysql_real_escape_string($_POST['to']);
$from_name = mysql_real_escape_string($_POST['from_name']);
$body = mysql_real_escape_string($_POST['body']);
$reply_id = mysql_real_escape_string($_POST['reply_id']);
$body = nl2br($body);
// add message to db
if($from!='0'){ // BB
$additem = mysql_query("
insert into user_messages (
from_userid,
to_userid,
from_name,
message_contents,
reply_to_id,
msg_read
)
VALUES (
'$from',
'$to',
'$from_name',
'$body',
'$reply_id',
'No'
)",$db
);
if(!$additem) { echo mysql_error(); exit; } // debug
// send email notif for message
$result20 = mysql_query("select name, emailaddr from users where (user_id = '$to')",$db);
if(!$result20) { echo 'result error'; echo mysql_error(); exit; } // debug
$databack20 = mysql_fetch_array($result20);
$title = 'title';
$currentdate = date("d");
$month = date("m"); // "02"
$currentmonth = date("F", mktime(0, 0, 0, $month));
$currentyear = date("Y");
$email = file_get_contents('/home/public_html/pages/html_email_templates/buddymessage.php');
$email = str_replace(">name<","$from_name",$email);
$email = str_replace(">name2<","$databack20[name]",$email);
// setting Content-type header
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
// Additional headers
$headers .= 'From: siteName <info@siteName.com>' . "\r\n";
//send mail
mail("$databack20[emailaddr]", "siteName Message", "$email", "$headers");
$success = "Message sent to $databack20[name]";
} // BB
} // AA
答案 0 :(得分:5)
这里真正的问题似乎是任何人都可以提交任何POST
请求,而您不会检查它是否真的是他们。 真的很容易制作一个执行以下操作的机器人(并在00
而不是from
中使用0
,因此绕过了您的“安全” - 我建议投射改为使用int:$from = (int)$from
,然后检查if ($from > 0)
,但这不是你真正的问题):
POST http://www.domain.com/contact.php
行动= <强>接触强>&安培;
从= <强> 00 强>&安培;
体= 垃圾强>&安培;
FROM_NAME = <强>垃圾邮件发送者强>&安培;
到= <强> 1 强>POST http://www.domain.com/contact.php
行动= <强>接触强>&安培;
从= <强> 00 强>&安培;
体= 垃圾强>&安培;
FROM_NAME = <强>垃圾邮件发送者强>&安培;
to = 2 &lt; - 在循环中永远增加
它甚至可以用PHP编写,如下所示:
<?php
$curlHandle = curl_init();
for ($i = 1; $i < 10000; $i++) {
curl_setopt_array($curlHandle, array(
CURLOPT_URL => "http://www.domain.com/contact.php",
CURLOPT_POST => true,
CURLOPT_COOKIE => "cookieName: yep",
CURLOPT_POSTFIELDS => array(
"action" => "contact",
"from" => rand(1, 10000),
"to" => $i,
"body" => "Spam",
"from_name" => "Spambot"
)
));
curl_exec($curlHandle);
}
?>
所以你应该检查一下$_SESSION
cookie来查看它的来源。也许还限制一个人只能每隔 nth 分钟发送一条消息。
答案 1 :(得分:0)
如果没有关于攻击者方法的内幕知识,我们无法直接回答&#39;题。但是,这里有一些可能有用的步骤。
PHP已弃用mysql_*
函数,转而使用PDO。您应该更新代码以使用PDO来利用它提供的新安全功能。
此外,请验证对数据库的访问权限是否已受到损害。您可能需要检查数据库日志以查找意外登录事件。
与此同时,在重写代码时,请考虑使用更安全的$ _SESSION调用替换以下行:
if (!isset($_COOKIE['cookieName'])) { header("Location: /userlogin.html); }
使用此代码时,恶意用户可以创建cookie以绕过您的登录要求。
答案 2 :(得分:0)
您的问题是攻击者在那里填写一个非整数值,该值由数据库转换为整数:零。
检查$from
是否为整数:
if ($from > 0 && (string)((int)$from) === $from) { /* ... */ }
P.s。:您应该将用户数据存储在$_SESSION
中,而不是让用户可以操纵隐藏的输入。