代码之家  ›  专栏  ›  技术社区  ›  Lotus Notes

这种用户身份验证方法有哪些弱点?

  •  4
  • Lotus Notes  · 技术社区  · 16 年前

    我正在开发自己的php框架。似乎我读过的所有安全文章使用的用户身份验证方法与我使用的方法大不相同,因此我可以使用一些帮助来查找安全漏洞。

    一些在我开始之前可能有用的信息。我对mvc url使用mod_rewrite。密码使用每个用户独有的24个字符的salt加密。mysql-real-escape-string和/或变量类型转换,以及htmlspecialchars。

    逐步过程:

    每页顶部:

    session_start();
    session_regenerate_id();
    

    如果用户通过登录表单登录,则生成新的随机令牌放入用户的mysql行。散列是根据用户的salt(从他们第一次注册时开始)和新令牌生成的。将哈希和明文用户名存储在会话变量中,如果选中“记住我”,则在cookie中复制。

    在每一页,检查饼干。如果设置了cookie,请将其值复制到会话变量中。然后将$_session['name']和$_session['hash']与mysql数据库进行比较。如果所有cookie和会话变量不匹配,则销毁它们,以便它们必须重新登录。

    如果登录有效,mysql数据库中的一些用户信息将存储在一个数组中,以便于访问。到目前为止,我假设这个数组是干净的,所以当限制用户访问时,我引用user.rank并拒绝访问,如果它低于该页面的要求。

    我试过测试所有常见的攻击,如xss和csrf,但也许我只是不够擅长黑客我自己的网站!我的系统看起来太简单了,实际上不安全(安全代码只有100行)。我错过了什么?

    编辑:对于从控制器调用函数,任何使用除select查询以外的任何查询都需要$u post数据来确认删除,例如,除了用户排名要求之外。

    我也花了很多时间搜索mysql_real_escape string的漏洞,但是我没有找到任何最新的信息(所有的东西至少都是几年前的,显然已经修复)。我只知道问题与编码有关。如果这个问题今天仍然存在,我该如何避免呢?

    我从某处借用并修改的加密函数:

    public function encrypt($str, $salt = NULL) {
        if ($salt == NULL) $salt = substr(md5(uniqid(rand(), true)), 0, 24);
        else $salt = substr($salt, 0, 24);
        return $salt.sha1($salt.$str);
    }
    
    6 回复  |  直到 16 年前
        1
  •  4
  •   Community Mohan Dere    9 年前

    帮你自己一个忙 标准图书馆 为了散列你的密码。

    由于安全性往往比大多数程序员单独解决的问题复杂得多,而且有更多不可见的出错可能性,因此使用标准库几乎总是最简单、最安全(如果不是唯一的话)的选择。

    标准图书馆 :
    看看: Portable PHP password hashing framework : 磷灰石 并确保使用 CRYPT_BLOWFISH 算法如果可能的话。

    使用phpass(v0.2)的代码示例:

    require('PasswordHash.php');
    
    $pwdHasher = new PasswordHash(8, FALSE);
    
    // $hash is what you would store in your database
    $hash = $pwdHasher->HashPassword( $password );
    
    // $hash would be the $hashed stored in your database for this user
    $checked = $pwdHasher->CheckPassword($password, $hash);
    if ($checked) {
        echo 'password correct';
    } else {
        echo 'wrong credentials';
    }
    

    PHPASS已经在一些相当有名的项目中实施:

    • PHPBB3
    • WordPress 2.5+和BBPress
    • Drupal7发行版(模块可用于Drupal5&6)
    • others

    好的是你不需要担心细节,那些细节已经被有经验的人编程,并在网上被许多人评论过。

    不管你做什么如果你去 我自己做,谢谢 方法, 不要使用 MD5 不再 . 这是一个很好的散列算法,但是 出于安全目的完全崩溃 .

    目前,使用 crypt ,使用crypt_blowfish是最佳实践。
    php中的crypt_blowfish是bcrypt散列的一个实现。bcrypt基于blowfish分组密码,利用其昂贵的密钥设置来降低算法速度。

    有关密码存储方案的更多信息,您还可以阅读 Jeff `关于它的博客文章: You're Probably Storing Passwords Incorrectly

        2
  •  2
  •   Carson Myers    16 年前

    我看那里没有什么真正的预防csrf攻击的措施。csrf(据我所知)是网站中最常被忽视/搞砸的漏洞。很多大人物都是通过csrf漏洞被黑客攻击的。

    当前解决此问题的最佳方法是使用 synchronizer tokens.

    对于如何正确地转义/编码用户输入,您最好非常虔诚。必须对插入数据库的内容进行转义,并且必须根据上下文对返回给用户的内容进行编码:css、html、javascript等都必须进行不同的编码。

    此外,您不应该将sha-1与md5结合起来。虽然sha-1比md5更强大,但通过将其与md5结合,实际上是在削弱它。此外,这两种算法都不推荐用于新的应用程序。目前,您应该使用sha-256(它在php中是现成的)。

        3
  •  2
  •   symcbean    16 年前

    试图过度设计这种方法可能会破坏安全性。

    你在使用什么会话处理程序?您是否检查过session_regent_id()重命名现有会话而不是复制该会话?如果是后者,则创建大量会话文件,通过随机搜索更容易找到。

    如何处理用户拆分会话?这一行代码将根据浏览器和用户如何分割会话而中断。

    您应该使用session_regent_id()的唯一地方是在对用户进行身份验证和用户注销时。

    mysql_real_escape_string和/或变量类型转换

    不,不,不。一直都是这样。

    不会更改传入数据的表示形式。无论如何/validate/input,您应该始终/sanitize/output,而不是/sanitize/input。

    如果用户通过登录表单登录,则生成新的随机令牌放入用户的mysql行。散列是根据用户的salt(从他们第一次注册时开始)和新令牌生成的。将哈希和明文用户名存储在会话变量中,

    没有什么能提高你的安全性

    将哈希和明文用户名存储在会话变量中,如果选中“记住我”,则在cookie中复制

    所以你把明文密码储存在用户机器上!这是 所以 不安全。如果你想要一个记住我的功能,那么用盐加密密码和有效期并存储。

    在每一页,检查饼干。如果设置了cookie,请将其值复制到会话变量中。

    所以用户可以通过返回同名的cookie来操作会话中存储的任何值?好的,所以他们可能无法预测散列,所以伪装用户是很困难的,但是有很多其他的方法可以用来破坏你的系统。

    你已经尽力使你的系统安全-但你实际上所做的最多是混淆了你的系统中正常工作的部分。

    C.

        4
  •  0
  •   mattoc    16 年前

    您可能需要对照白名单检查user.rank,以确保该值存在于查找表中且有效(活动、未删除等),并强制进行类型转换和范围设置。

    至于令牌,您将希望为期望从表单接收get/post数据的每个页面生成一个新的令牌。如果会话被劫持,则会话的令牌可能不足。为会话设置较短的超时时间可以减轻这种影响。

    不要马上相信饼干里的任何东西,考虑使用 http://php.net/manual/en/book.filter.php 在会话中隐藏之前。

    如果您计划为系统设置一个管理面板,那么最好强制设置密码强度,手动选择管理员登录名(在设置时优先选择管理员/密码库存登录)。

    黑名单通常的登录名,如“A”;删除数据库…”和“管理员”,你知道演习。

    使用最低权限帐户设置数据库时,您不希望访问者破坏您的表。

        5
  •  0
  •   middus    16 年前

    “密码是sha1和md5加密的”

    为什么需要使用两个散列函数?我想你这样做是因为缺乏理解(没有冒犯!)。你应该读 this article on secure password schemes (提示:使用bcrypt)。

        6
  •  0
  •   Your Common Sense    16 年前

    使用session_regent_id();您将使浏览器中的“后退”按钮不可用。 但仍然结合“记住我”的功能,它变得毫无用处。
    我看不出你描述中的csrf防御
    mysql\u real\u转义字符串没有任何问题