这个PHP代码中的任何漏洞/可能的优化来检测是否需要CAPTCHA?

时间:2011-12-05 21:41:12

标签: php mysql captcha verification

我想问下面写的代码是否有任何漏洞(可能对其他人有用)。此代码检查在过去5分钟内是否有超过5次尝试登录。由ip和userid检查。每次登录尝试都存储在历史表(MySQL)中。

历史表仅用于CAPTCHA显示的目的。 ENGINE = InnoDB被选中。 (您是否建议使用MyISAM以获得更好的性能?您是否建议将索引放在Time或userid或remote_addr上?)

有关优化的任何建议吗?可能的漏洞? 谢谢。

$query1="SELECT id FROM history WHERE (Time>date_sub(now(), interval 5 minute)) AND remote_addr='".ip2long($_SERVER['REMOTE_ADDR'])."' limit 6"; //limit 6 is for performance, 6+ means 6, we only care if it less than 5
$result1=mysql_query($query1);
//so we know mysql_num_rows($result1)


$query2="SELECT id FROM history WHERE (Time>date_sub(now(), interval 5 minute)) AND userid='".$userid."' limit 6";//limit 6 is for performance, 6+ means 6, we only care if it less than 5
$result2=mysql_query($query2);
//so we know mysql_num_rows($result2)



$attempts=0;//we want to set up $attempts=maximum of (mysql_num_rows($result1), mysql_num_rows($result2))
if($result1) {
    $attempts=mysql_num_rows($result1);
}
if($result2 && $attempts<mysql_num_rows($result2)) {
    $attempts=mysql_num_rows($result2);
}

//if $attempts is more than 5, then CAPTCHA should be displayed, if less then it should not

P.S。你是否仍然建议使用usleep(100000)或任何其他方法来防止暴力,如果有人写了一天algorythm(直到验证码再次变强)来破解验证码?

补充:谢谢你的询问,是的,$ userid是从坏符号中清除的。

1 个答案:

答案 0 :(得分:3)

如果对$ userid进行了清理,则没有安全问题,但我会提供以下更改以使代码更有效:使用MySQL的COUNT函数而不是返回六个ID号。如果您不需要使用ID,请不要检索它们。此外,我认为没有理由两次查询数据库。把它削减一点。

以下代码更短,更快,更安全(使用mysql_real_escape_string() - 我建议您查看该功能)。我们消除了一个查询,一些if语句,并节省了通过网络发送不必要的数据:

$userid = mysql_real_escape_string('...');
$ip = ip2long($_SERVER['REMOTE_ADDR']);

$q = "SELECT COUNT(*) AS cnt FROM history 
  WHERE Time > date_sub(now(), interval 5 minute)
  AND (remote_addr='$ip' OR userid='$userid')
";
$r = mysql_query($q);

// first value, first row (we only get one using count)
$attempts = mysql_result($r, 0, "cnt");

// if $attempts is more than 5, then CAPTCHA should be displayed ...