请批评我的PHP身份验证工作

时间:2009-03-03 18:27:04

标签: php authentication login

在一段时间后发布this之后,我决定在PHP中创建自己的注册/身份验证功能。我希望任何人都能指出改进的缺陷/机会,特别是在会议中存储的内容......

逻辑流程是:

1 - 用户注册使用电子邮件作为用户名,“网站名称”然后构成他们可以访问的任何网址的一部分,密码至少6个字符,必须包含字母和数字(我知道这可能是强)

2 - 如果用户和站点是唯一的,那么我将这两者以及随机生成的字符串(salt)存储在我数据库的auth表中的一行中。然后我获取用户密码,将salt连接到它,并将此salted密码的md5哈希存储在同一个数据库行中

3 - 当用户登录时,我会输入她输入的密码并将盐连接到它,创建一个md5哈希值,并将其与我存储在数据库中的密码进行比较 - 如果它们匹配,则用户输入了正确的密码,并将其用户名写入会话

4 - 在每个请求中,我使用会话中存储的用户名来查询数据库并读取与此用户关联的站点名称。然后我将它与url本身的站点名称进行比较,如果它们匹配,我设置一个可供其余或脚本访问的变量(不是全局变量,它只能由我的控制器读取,它决定用户是否可以看到特定页面)如果两个站点名称不匹配,则将用户重定向回登录

我担心的是有人可以写入会话,因此如果他们知道他们注册的用户名,就可以访问人们的页面吗?你会如何防止这种情况发生?

在任何人因为这是个人学习项目的方式指责我疏忽之前 - 我没有公开任何客户数据!

6 个答案:

答案 0 :(得分:8)

  1. 为什么有6个字符?使其更大,并且至少需要6个(或更多)字符。没有理由将密码中的字符数限制为6。

  2. 在会话中输入多个用户名。但要安全地执行此操作,您必须在每次登录时更改盐:

  3. A-从登录页面:使用现有盐进行名称和密码验证。如果有效,用新盐更新用户表盐和密码(你有来自用户的密码,所以你可以md5和盐再次)。将密码的md5写入会话。 B-从任何其他页面:将用户和散列密码与数据库进行比较。如果它们不匹配,请重定向到登录页面。

    这个想法的缺陷是用户无法在多台机器/浏览器上维护登录。

    您的注册系统需要工作。你怎么知道这个电子邮件地址有效?您如何知道用户注册拥有电子邮件地址?您必须向包含返回您网站的链接的地址发送电子邮件,在您允许帐户访问任何内容之前必须单击该链接。否则,有人可以在其他人的电子邮件地址下注册,向该人提出欺诈性声明,或者只是让您的网站向该网站发送垃圾邮件,让您的网站关闭。

    您可能还想调查CAPTCHA以限制脚本注册。

答案 1 :(得分:3)

简短的回答:看起来不错!

答案很长:

  1. 是的,您应该允许更强/更长的密码,否则这是可以的。只需确保您只接受有效的网址部分字符(我会坚持使用PCRE字符)作为网站名称。但是,“验证此电子邮件”系统是合适的,以确保注册人实际控制提供的电子邮件地址。
  2. 看起来不错。不过,我比shad更喜欢sha1。
  3. 只要您的会话安全,您就可以存储的不仅仅是用户名(对于每个页面请求,这将是一个相当昂贵的SQL查找 - 继续存储他们的PK)。
  4. 看起来不错,但应根据我在#3
  5. 中的评论进行调整

    要确保正确处理会话安全,请检查the guide on PHPSec

答案 2 :(得分:3)

  • 限制登录时的速度。记录用户的每次尝试,并在经过多次失败尝试后将其锁定。当失败的尝试安装时,锁定越来越长。

  • 在代码中添加一个静态的salt,并将其与数据库中的salt结合使用。然后,如果你的数据库被黑客攻击,他们仍然没有代码中的盐。这种盐不能/不应该改变。

  • 用户可以检索密码/重置锁定吗?你需要收集挑战问题和答案。

  • 当用户重置密码时,他们是否必须知道原密码?

如果这是一个安全的网站,或只是一个跟踪某人的网站。我知道您可以从机器到机器登录的网站。它总是记得你,但只是一个论坛,所以麻烦的可能性很低。

为什么要加密代码以及数据库? 一旦您的数据库遭到黑客入侵,您的网站就会被祝酒。然而,看到用户倾向于在许多网站上使用相同的密码,没有任何意义帮助破解每个人的财产。如果他们也得到你的代码,那么王室​​的拧紧就会发生,但是我们尽可能多地设置障碍。

通过默默无闻的安全是愚蠢的,但许多安全层可以提供帮助。

关于在会话中输入用户名 哈希用户名,网址和盐。将其存储在数据库和会话中。使用它作为身份验证,如果无效则将它们转储到登录名。他们不能将cookie复制到另一个站点,他们不会公开他们的用户名,并且它会消除查询。

您甚至可以在每个X页面视图中重新生成该盐值并将其存储在会话中以使其过期,并且随着时间的推移窃取它不那么有用。然后,您将在数据库中存储两个盐。一个用于密码,一个用于验证会话值。

答案 3 :(得分:1)

如果有人正在观看提交的注册表单,那么他们就会知道您所关注的信息。第一步:对表单使用HTTPS。

至于加密的数据库内容,我会让别人对此提出异议。 : - )

答案 4 :(得分:1)

  

我担心的是有人可以写入会话,因此如果他们知道他们注册的用户名,就可以访问人们的页面吗?你会如何防止这种情况发生?

我不确定你的意思。怎么会有人“写到会议”?会话[通常]是存储在服务器上的文件,客户端无法查看或修改该文件。

如果您担心会话劫持(也就是固定),那么您需要在URL字符串中启用SSL并禁用会话ID。 (参见php.ini的session.use_only_cookies

  

4 - 在每个请求中,我使用会话中存储的用户名来查询数据库并读取与此用户关联的站点名称。然后我将它与url本身的站点名称进行比较,如果它们匹配,我设置一个可供其余或脚本访问的变量(不是全局变量,它只能由我的控制器读取,它决定用户是否可以看到特定页面)如果两个站点名称不匹配,则将用户重定向回登录

这听起来像是最大的担忧。网站名称是什么样的?你是如何将它与URL匹配的?正则表达式?

有关这方面的更多细节会很好,因为如果您的访问控制存在缺陷,那么您的身份验证质量就无所谓了。

答案 5 :(得分:0)

如果我得到正确的流程,那么如果我知道您的用户名和网站名称,请转到网站名称并为您提供一个包含用户名的cookie(因为会话,毕竟保存为Cookie),我在 - 不需要密码?这不是一个缺陷吗?