在制作我的新网站时,我需要新的登录脚本,所以我对数据感到满意。我之前制作过这样的剧本,但谁知道他们有多安全。希望在网上找到一些答案我发现这样一个自称“超级安全登录脚本”的教程。您可以在此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']与之后的内容或什么进行比较?
答案 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作为密码。