PHP登录安全性

时间:2011-03-10 19:22:56

标签: php

这就是我构建登录系统的方式:

登录

  1. 检查用户使用数据库提供的用户名和密码。
  2. 如果用户名和密码正确无误,请在会话中存储 仅用户ID ,例如:

    $ _ SESSION [ '用户ID'] = $用户ID;

  3. 如果用户选中了保持登录的选项,则设置2个cookie,1个带有userID和其他散列字符串。

  4. 检查用户是否已登录:

    1. 检查会话是否存在,用户是否已记录。 没关系?
    2. 如果会话不存在,请检查cookie,userID和散列字符串是否都存在。
    3. 如果两个Cookie都存在,请验证它们。
    4. 由于会话存储在服务器中,仅存储userID是否安全?用户可以伪装成其他用户并将他的用户ID存储在会话中并以他身份登录吗? 感谢。

7 个答案:

答案 0 :(得分:4)

是的,这种方法非常不安全。我可以嗅到流量,拦截你的cookie,你的系统会接受我作为一个经过身份验证的用户。您假设如果您获得带有用户标识和散列字符串的cookie,则该用户与最初进行身份验证以创建cookie的用户相同。这是一个很糟糕的假设,因为cookie以纯文本形式传播(除非你加密它们),所以只要我能抓住一个cookie,我就可以假装是谁发送了那个cookie,你的系统也不知道更好。

编辑:

如果您要使用未加密的cookie,为什么不将session_id存储在数据库表中?这样,至少持有cookie的人将没有有效的用户名。创建会话表,当有人成功通过身份验证时,添加一行及其user_id和session_id。每次加载页面时,请检查cookie中的session_id是否与sessions表中的行匹配。如果是,则可以假定关联的user_id是经过身份验证的用户。这种方法与您建议的方法一样安全(即不是很安全),但它不那么复杂,也不会泄露有效的用户名。

答案 1 :(得分:2)

是的,有可能并且非常广泛,这种攻击被称为Session fixation,并且在你的系统中(正如大卫所说)任何嗅到你的流量,或者访问用户的驱动器并偷走他的饼干的人都可能取而代之已登录的用户。

最好的保护当然是SSL,但是如果你不能在你的网站上使用它,还有其他的东西可以防止(但不能完全防止)这种攻击:

  • 在登录时保存用户在服务器端的信息,对此的良好候选者是IP和user agent,但是其中任何其他数据都没有变化整个会话都有效。
  • 您可以在每个请求中重新生成会话ID,如果会话ID泄露,则攻击者必须在真实用户执行任何其他请求之前使用它,但请注意,因为每次重新生成会话ID时(至少在PHP中) )用户的会话数据被重新,因此如果您拥有大量用户或者保存每个用户的许多数据,这可能会很昂贵(这意味着,如果您要保存会话数据)一个文件,该文件将被删除,创建和再次写入。)

好吧,现在我只能想到这两个,它并不多,但至少你会给攻击者带来额外的复杂性。

还有一件事,不要相信用户的cookie,用户(或攻击者)可以随时更改它们,将其视为任何其他用户输入。

PD:很抱歉我的英语很糟糕,我真的想改进它^ _ ^

答案 2 :(得分:0)

您可以添加用户ID应该属于的ip(在您的数据库中),这会增加一些额外的安全性 - 它可能并不总是最佳解决方案

答案 3 :(得分:0)

是的,可以检查会话是否存在,还检查用户ID是否大于零。

“记住我”功能会受到嗅探,因为它不会超过ssl,但这就是“记住我”功能的完成方式。

答案 4 :(得分:0)

假设这是通过SSL发生的,我最关心的是你的第一步:

  
      
  1. 检查用户使用数据库提供的用户名和密码。
  2.   

您应该使用哈希密码,并将用户提供的密码的哈希值与数据库中存储的先前哈希密码进行比较。

您也不必担心在会话数组中仅存储 用户ID;会话存储在服务器端,与服务器的其他部分一样安全。

答案 5 :(得分:0)

一个潜在的问题是所有内容都存储在cookie中。如果某人设法获得会话ID,那么他们也会获得用户名和哈希字符串。

Chris Shiflett从User-Agent字符串或其他常规标题中建议creating some kind of fingerprint,并将其存储在GET变量中。

提高安全性的一种方法是通过SSL发送所有。任何时候发送或接收任何类型的潜在信息(例如cookie中的会话ID),都要加密 - 而不仅仅是登录表单。

答案 6 :(得分:-1)

这大多是正确的,但我不同意cookie选项。这样,如果有人获得两个cookie,可以将它们移动到另一台计算机并仍然使用它们。

“保持登录”功能应限制在该计算机上。一种可能的解决方案是,如果用户希望保持登录状态,则将会话的生命周期设置为1周左右。此外,您还必须存储用户的IP地址,User-Agent和可能的X-FORWARDED-FOR标头,并根据存储的值检查每个页面加载。

相关问题