php登录身份验证令牌\u id和登录脚本在网络上找到-安全?

php登录身份验证令牌\u id和登录脚本在网络上找到-安全?,php,authentication,login,Php,Authentication,Login,在创建我的新站点时,我需要新的登录脚本,这样我就可以放心地使用我的数据。我以前做过这样的脚本,但谁知道它们有多安全。希望能在网上找到一些答案,我找到了这样一个自称为“超级安全登录脚本”的教程。你可以在这里找到它 我想知道它到底有多安全,它容易受到什么样的威胁 我在代码行中还发现如下内容: // Create Second Token $tokenId = rand(10000, 9999999); $query2 = “update users set tokenid = $tokenId wh

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

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

我在代码行中还发现如下内容:

// 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;

它应该如何工作?它阻止了什么?我是否应该将$\u SESSION['token\u 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\u real\u escape\u string()
不存在,它会返回到
mysql\u escape\u string()
。您永远不应该回到mysql\u escape\u string()。如果mysql\u real\u escape\u string()不可用,并且您依赖它来避免SQL注入,那么您的应用程序应该停止。 另一个问题是它使用了
strip\u tags()
。SQL注入的转义和XSS的转义/编码是两件不同的事情,不应该合并为一件

我建议使用MySQLi准备的语句或PDO参数化查询来代替此函数,以避免SQL注入

为了避免XSS,无论何时打印来自数据库(或直接用户输入)的内容(源自用户输入),都要使用
htmlentities()

2) 这是坏习惯

$_SESSION[userid] // this should have single quotes, making it $_SESSION['userid']
3) PHP逻辑和HTML混合在一起,不需要将它们分开

4) 登录表单上的验证码。这只会让用户不高兴。通常登录表单上不需要验证码

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

作者的代币意向

这真的是任何人的猜测,但也许随机数是用来在密码重置链接。 对于这类事情,通常会对随机数/字符串进行散列,而不是保留一个短的随机数。而且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

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

$\u会话['userid']

在查询中使用
$\u SESSION[userid]
来解决由于引号导致的查询中断问题,表明缺乏知识/经验

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

$sql = "SELECT * FROM table WHERE something = '" . $_SESSION['something'] . '";
当然,如果不确定变量的内容,则需要转义SQLi(最好使用参数化查询)

验证码

在正确的地方使用验证码非常好。像这样的登录表单不是其中之一。你可以在X次尝试失败后使用验证码(就像谷歌那样),但不是像这样一直需要验证码。 还有其他处理暴力登录尝试的方法,这里有几个答案


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

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

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

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\u real\u escape\u string()
不存在,它会返回到
mysql\u escape\u string()
。您永远不应该回到mysql\u escape\u string()。如果mysql\u real\u escape\u string()不可用,并且您依赖它来避免SQL注入,那么您的应用程序应该停止。 另一个问题是它使用了
strip\u tags()
。SQL注入的转义和XSS的转义/编码是两件不同的事情,不应该合并为一件

我建议