关于网站用户身份验证的PHP最佳实践?

时间:2011-05-03 23:23:10

标签: php authentication

我使用非常简单的php代码构建了几个站点,到目前为止一直很好,但我发现我现在担心主题“安全性”我想知道在PHP中创建登录/身份验证过程的最佳方法是什么? / p>

这就是我目前所做的事情:

在注册期间,用户提交电子邮件和密码 密码将作为md5字符串存储在mysql中,所以除了用户之外的任何人都知道它。

当用户登录时,我会

SELECT * FROM usertable WHERE email = $emailsubmitted AND pass = md5($passsubmitted)

然后,如果结果数组的大小大于零,则表示用户存在

所以我设置了

session_start(); 
$_SESSION['logged'] = 'true';
$_SESSION[userid] = userid;

因此,对于用户浏览的每个页面,我将执行检查以查看会话变量是否存在。

BOTTOM LINE:我想知道这是否足够安全以及如何改进它。

4 个答案:

答案 0 :(得分:3)

您的SQL语句中存在一个注入漏洞。 (这是假设“提交”后缀意味着变量未对其进行任何过滤。)如果恶意用户要提交'admin@example.com' AND 1=1;--作为电子邮件地址,他们可以使用凭据登录“admin@example.com”,无论密码如何。我建议保护SQL的输入和/或使用存储过程。我还建议只加载你绝对需要的列;它将提高查询的速度,并允许较少的状态在数据库之外暂停。

此外,在密码上实施salting。如果有人要从数据库中检索用户的数据,那么密码将成为暴力破解和字典攻击的简单目标(如彩虹表)。如果你真的很偏执,可以考虑从MD5切换到SHA或其他散列函数。

确保在php.ini文件中设置了哪些变量,并将它们设置为您期望的值。根据这些设置,$_SESSION的数组分配也是不安全的。一些旧的Web应用程序使用PHP“功能”,这使得查询字符串中的变量成为Web应用程序中的全局变量,这意味着当它执行$_SESSION['userid'] = $userid;时,如果恶意用户将?userid=1附加到其查询中字符串,他们将成为用户ID为1的用户,通常是第一个用户(或管理员)。

答案 1 :(得分:1)

一般逻辑是好的,是的。但是,密码的简单md5并不好。

  • 不对密码进行腌制会使哈希打开彩虹表查找。

  • md5通常不被认为是密码的良好散列机制。我建议您查看http://www.openwall.com/phpass/

附注:您的SQL 似乎对SQL注入开放。

答案 2 :(得分:1)

除了前面提到的SQL注入之外,我建议您不要检查数组是否大于零,而是检查数组是否等于1。

原因是让我们说有人会修改你的数据库,只是运行一个简单的查询来清除所有密码或将它们设置为一个特定的条目,然后检查等于一个会阻止它。

另外,假设多个用户拥有相同的密码,并且他们以某种方式SQL注入了用户名,或者您忘记检查用户名,那么再次检查等于一个是安全的。

最终,这是一件小事,但在安全方面,每一点点都很重要。

答案 3 :(得分:0)

我注意到的第一件事是你将MD5哈希应用于php变量。 这让我觉得密码在频道上传输清晰。

你应该在这里使用js将MD5哈希客户端应用于一个例子:

http://phpjs.org/functions/md5/

如果要添加另一层安全性,除了标准哈希之外,还应考虑使用salt。这样可以保护您免受任何攻击或反向攻击(参见:http://tools.benramsey.com/md5/