php登录身份验证token_id和在网上找到的登录脚本-安全


php login authentification token_id and login script found on the net - secure?

在创建新网站时,我需要新的登录脚本,这样我就可以放心地使用我的数据了。我早些时候做过这样的脚本,但谁知道它们有多安全。希望能在网上找到一些答案,我发现了这样一个教程,它自称为"超级安全登录脚本"。你可以在这个链接中找到它

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

我还在代码行中发现了这样的内容:

// 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) 它逃避用户输入以避免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_eescape_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()或htmlenties()。如果在某个时刻,出于任何原因,您希望允许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(就像谷歌一样),但不是像这样一直需要它。还有其他处理暴力登录尝试的方法,SO.上有几个答案

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