在网上找到php登录身份验证令牌ID和登录脚本 - 安全吗?

时间:2012-03-13 13:58:59

标签: php authentication login

在制作我的新网站时,我需要新的登录脚本,所以我对数据感到满意。我之前制作过这样的剧本,但谁知道他们有多安全。希望在网上找到一些答案我发现这样一个自称“超级安全登录脚本”的教程。您可以在此link

中找到它

我想知道它到底有多安全,以及它容易受到什么样的威胁。

我也在这样的代码行中找到了:

// Create Second Token
$tokenId = rand(10000, 9999999);
$query2 = “update users set tokenid = $tokenId where userid = ‘$_SESSION[userid]‘”;
$result2 = mysql_query ($query2);
$_SESSION['token_id'] = $tokenId;

它应该如何运作?什么阻止了?我应该将$ _SESSION ['token_id']与之后的内容或什么进行比较?

1 个答案:

答案 0 :(得分:1)

您发布的代码只是创建一个随机数,然后将其存储在用户数据库表中的用户记录中,然后将其存储在会话中。 根据提供的链接,令牌或随机数实际上根本不会用于任何事情。您必须向开发人员询问其含义。

出于以下原因,我不推荐您链接的登录脚本:

1)它逃避用户输入以避免SQL注入的方式

以下是使用的功能:

function escape_data ($data) {

 // Check for mysql_real_escape_string() support.

 // This function escapes characters that could be used for sql injection

 if (function_exists(‘mysql_real_escape_string’)) {

 global $dbc; // Need the connection.

 $data = mysql_real_escape_string (trim($data), $dbc);

 $data = strip_tags($data);

 } else {

 $data = mysql_escape_string (trim($data));

 $data = strip_tags($data);

 }

 // Return the escaped value. 

 return $data;

 } // End of function.

上述功能存在一些问题。最大的问题是,如果发现mysql_real_escape_string()不存在,则会回退到mysql_escape_string()。你永远不应该回到mysql_escape_string()。如果mysql_real_escape_string()不可用并且您依赖它来避免SQL注入,那么您的应用程序应该停止。 另一个问题是使用strip_tags()。针对SQL注入的转义以及针对XSS的转义/编码是两回事,不应合并为一个。

我建议使用MySQLi预处理语句或PDO参数化查询代替此函数,以避免SQL注入。

要避免使用XSS,只要打印出源自用户输入的数据库(或直接用户输入)内容,就使用htmlentities()

2)这是不好的做法

$_SESSION[userid] // this should have single quotes, making it $_SESSION['userid']

3)PHP逻辑和HTML混合在一起,没有努力将它们分开。

4)登录表单上的CAPTCHA。这只是让用户不高兴。通常,登录表单上不需要CAPTCHA。

编辑 - 我在评论中回答了您的一些观点。

作者对令牌的意图

这是任何人的猜测,但也许随机数意味着用于密码重置链接。 对于那种事情,通常进行哈希随机数/字符串而不是保留一个短的随机数。 mt_rand()也比rand()好。

使用单个函数进行SQLi转义和XSS预防

这是个坏主意,因为它们是两个非常不同的东西。 SQLi的转义是在数据库的入站完成的,如果你看到我的意思,应该在出站时进行XSS预防。

在数据库中存储数据时,通常最好以原始形式存储,而不是使用strip_tags()或htmlentities()。如果在某些时候您希望允许HTML出于任何原因输入数据库,该怎么办?

XSS预防应该在数据从数据库出来到页面或从哪里进入时完成。如果要将数据输出到HTML以外的其他介质(如XML或Web服务),并且已经为HTML处理了该数据,该怎么办? XSS和SQLi的单个函数不会使代码更清晰,它会将进程应用于当时不需要应用的数据。

查看任何流行的框架,如Zend,或CMS,如WordPress,Joomla等。它们都没有为SQLi和XSS使用单一功能。

混合使用PHP和HTML

是的你是对的它不会影响安全,但它看起来很糟糕。它难以阅读,难以维护,难以扩展和更新,并且绝对是我不推荐它的原因。

$_SESSION['userid']

中的引号

在查询中使用$_SESSION[userid]来解决由于引号导致查询中断的问题,显示缺乏知识/经验。

您可以使用引号,只需将变量连接到查询中,如

$sql = "SELECT * FROM table WHERE something = '" . $_SESSION['something'] . '";

当然,如果你不确定变量的内容,你需要为SQLi转义(最好使用参数化查询)。

<强> CAPTCHA

CAPTCHA在适当的地方使用时非常棒。像这样的登录表单不是其中之一。 X尝试失败后可以使用CAPTCHA(就像谷歌那样),但不是这样,所有时间都需要它。 还有其他方法可以处理暴力登录尝试,这里有几个答案。

我没有提到的另一点是密码哈希。这是使用没有盐的SHA1,这不是很强。我会使用SHA256或更高版本,并使用salt作为密码。