Php 这种用户身份验证方法的缺点是什么?

Php 这种用户身份验证方法的缺点是什么?,php,mysql,security,session,Php,Mysql,Security,Session,我正在开发自己的PHP框架。似乎我读过的所有安全性文章都使用了与我截然不同的用户身份验证方法,因此我可以在查找安全漏洞时使用一些帮助 在我开始之前,一些可能有用的信息。我对我的MVC url使用mod_rewrite。密码使用每个用户独有的24个字符的salt进行加密。mysql\u real\u escape\u字符串和/或变量类型转换用于输入的所有内容,htmlspecialchars用于输出的所有内容 逐步过程: 每页顶部: session_start(); session_regener

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

在我开始之前,一些可能有用的信息。我对我的MVC url使用mod_rewrite。密码使用每个用户独有的24个字符的salt进行加密。mysql\u real\u escape\u字符串和/或变量类型转换用于输入的所有内容,htmlspecialchars用于输出的所有内容

逐步过程: 每页顶部:

session_start();
session_regenerate_id();
若用户通过登录表单登录,则生成新的随机令牌放入用户的MySQL行。哈希是基于用户的salt(从用户首次注册时开始)和新令牌生成的。在会话变量中存储哈希和明文用户名,如果选中“记住我”,则在cookie中复制

在每一页上,检查cookies。如果设置了Cookie,则将其值复制到会话变量中。然后将$\u会话['name']和$\u会话['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);
}
使用会话_重新生成_id();您将使浏览器中的“后退”按钮无法使用。但仍然与“记住我”功能相结合,它变得毫无用处。
我在你的描述中看不到CSRF辩护

mysql\u real\u escape string没有任何问题,您可能需要对照白名单检查user.rank,以确保该值存在于查找表中且有效(活动、未删除等),并强制类型转换和范围

至于令牌,您将希望为希望从表单接收GET/POST数据的每个页面生成一个新令牌。如果会话被劫持,则会话的令牌可能不足。为会话设置较短的超时时间可能会缓解此问题

不要马上从cookie中信任任何东西,考虑在会话中隐藏之前使用。

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

黑名单通常的登录名,如“a';DROP DATABASE…”和“Administrator”,你知道这个练习

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

密码是sha1和md5加密的


为什么需要使用两个哈希函数?我猜你这样做是因为缺乏理解(无意冒犯!)。您应该阅读(提示:使用bcrypt)。

我没有看到任何真正的CSRF攻击预防措施。据我所知,CSRF是网站中最常被忽视/弄糟的漏洞。许多大公司都通过CSRF漏洞遭到黑客攻击

目前解决这个问题的最佳方法是使用

对于正确地转义/编码用户输入,您最好非常虔诚。插入到数据库中的内容必须转义,输出回用户的内容必须根据其上下文进行编码:CSS、HTML、JavaScript等都必须进行不同的编码


此外,您不应该将SHA-1与MD5结合使用。虽然SHA-1比MD5强大,但通过将其与MD5结合,实际上是在削弱它。此外,这两种算法都不建议在新应用中使用。目前,您应该使用SHA-256(它在PHP中是现成的)。

帮自己一个忙,使用标准库对密码进行哈希运算

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

标准库
查看::phpass并确保尽可能使用
CRYPT\u-BLOWFISH
算法

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

PHPass已在一些知名项目中实施:

  • phpBB3
  • WordPress 2.5+以及bbPress
  • Drupal 7发行版(模块可用于Drupal 5和6)
好的是,你不需要担心细节,那些细节是由有经验的人编写的,并在互联网上被许多人审查过

无论你做什么,如果你选择“我自己做,谢谢你”的方法,不要再使用
MD5
。这是一个很好的散列算法,但出于安全目的,它完全被破坏了

目前,与CRYPT_河豚一起使用是最佳实践。
PHP中的CRYPT_河豚是一个实现
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';
}