2

所以我想设计一个高安全性的php用户系统。我决定从登录/会话结束开始。我希望有人查看我的计划并告知我漏洞和安全漏洞。

这是我第一次尝试在这样的级别上创建系统,如果您发现问题,可以向我发送资源以帮助我修复它。

连接到数据库 *我将使用 MYSQL,因此它是您的标准数据库连接,存储在站点根目录之外的文件中。

注册 *注册将是一个简单的表单,我使用存储在外部文件中的函数来清理输入并防止 SQL 注入

// A function to sanitize input for data being input into a database
function sanitizeinput($rawinput) {
$sanitizedinput = mysql_real_escape_string($rawinput);
return $sanitizedinput;
}

我需要这个功能来保护它吗?

密码是使用 SHA-512 或 BCrypyt 进行散列,我做了一些研究,看到很多人说 MD5 不再足够安全,我想确保最好的安全性,所以我应该使用什么来散列密码。

我还使用以下代码段添加了一个随机生成的盐,它附加到散列密码的前面,然后重新散列。然后盐以纯文本格式存储在数据库中,我是否应该考虑对其进行加密以提高安全性?

当用户登录时,他们输入的密码将被散列,来自数据库的盐添加并重新散列,然后与存储在数据库中的密码进行比较。

如果密码匹配,将创建一个会话,然后将其锁定到单个 IP 地址和用户代理。会话将在短时间内到期。会话将仅用于存储登录令牌,用户名和密码当然不会存储在会话中。

当用户登录时,令牌将被存储到数据库中,并分配给它的用户名,这样我们就可以使用令牌安全地从数据库中提取用户详细信息,而不会有将其存储在会话中的风险。

如果密码不正确,用户将无法登录……呃,我也会对此实施蛮力保护,三次尝试后,用户 IP 和用户代理将被锁定 15 分钟,十次失败尝试后被阻止在防火墙中。

我觉得我忘记了什么,但我不能将手指直接放在它上面。

任何帮助或建议将不胜感激。

4

4 回答 4

2

我绝不是这方面的专家,但首先切换到 PDO 以连接到 mySQL。如果使用得当,这似乎有点困难,但可以 100% 保护您免受任何试图进行 sql 注入的人的伤害。对于加密,我使用它为每个用户生成一个随机盐:

    function generateSalt($length, $chars)
{
  $randString = '';
  $charLength = strlen($chars);
  for($count = 0; $count < $length; $count++)
  {
    $randString .= substr($chars, mt_Rand(0, ($charLength-1)), 1);
  }
  return $randString;
} 

如果你给它一个字符串,它会从该字符串中的字符中吐出给定长度的盐。然后我相信我用了河豚,因为它不容易开裂。

你考虑过 XSS 漏洞吗?我还没有,需要继续。确保用户没有将 html 或 javascript 代码注入到您的数据库中,这些代码稍后可能会显示在页面的某个位置。

祝你好运。

编辑:这是我用于“散列”的内容

$cryptOptions = '$2y$10$' . $salt . '$';
$hashedPassword = crypt($password1, $cryptOptions);
于 2012-11-12T18:26:26.823 回答
0

抱歉,我无法评论 m02ph3u5 的帖子,所以我必须发布另一个答案。在数据库中存储盐是完全标准的。存在盐的原因是为了防止彩虹表的暴力破解。Rainbow 表是预先计算的哈希值,可以快速破解数据库中的所有密码。使用盐,即使是攻击者已知的盐,也无法预先计算彩虹表。这意味着人们必须暴力破解每个密码。这很好,因为如果你使用像河豚这样的算法,那么破解数百个密码就变得不切实际了。

这不是使密码无法破解的方法。这是一种使破解所有密码变得不切实际的方法。

编辑:如果他们可以访问您的数据库,他们将只有您的散列密码和盐。他们仍然需要纯文本密码。

EDIT2:所以他们的想法是他们可以访问该网站,所以我们当时唯一想做的就是保护密码。通常人们会重复使用密码。散列实际上只是为了保护这类人。

于 2012-11-12T18:37:22.040 回答
0

为什么要将盐存储在数据库中?假设有人可以访问您的数据库 - 他将拥有密码和盐。如果你有你的盐硬编码或其他地方他只会有散列密码。如果攻击者获得了对您系统的完全访问权限,这无关紧要。

另外,您会使用 https 作为登录程序吗?

假设您有多个数据库连接并且它们具有不同的编码 - 您应该将正确的链接传递给您的 sanitizer 函数。顺便说一句,用另一个不添加任何东西(但实际上限制实际功能)的函数包装 mysql_real_escape_string 有什么好处?我鼓励你使用 PDO。

于 2012-11-12T18:28:59.397 回答
0

几个月前用 Java 实现了一个类似的原型。

从我所见,它看起来与我所拥有的非常相似。我已经做过(或至少计划要做)的一些事情,我从你的解释中看不到

  1. 显然,使用 TLS 保护 HTTP 通道,否则您将以明文形式发送密码。
  2. 使用一些关键的拉伸功能,例如http://en.wikipedia.org/wiki/PBKDF2,这样蛮力攻击将更加计算密集。
  3. 我多次应用哈希。(我使用了 1024 次迭代),再次防止暴力攻击。如果我必须再做一次,我宁愿花时间实施 2。
  4. 会话应在最后一次访问的基础上过期。

希望能给你一些额外的想法。

于 2012-11-12T18:33:39.287 回答