注册,登录,会话和发布安全措施

时间:2014-12-18 19:57:07

标签: php security session cookies pdo

这是我第一次向任何人询问有关网站开发的问题。我之所以决定提出这个问题,是因为其他人之前提出过许多类似的问题,是因为其他人过去收到的答案数量和主观性都很大,所以我对如何处理这个问题感到困惑和怀疑。

我意识到有不同的方法可以解决这个问题,这就是为什么我的问题可能引起一些讨论,但我希望每个人都能记住我的问题的细节,如果有任何讨论:我不是在问什么是最安全的方法,但我的方法是否完全安全;我的目标是流行论坛的安全级别,而不是亚马逊或Paypal这样的大型公司网站。

我用的是什么:

  • PHP 5.5 for password_hash
  • PDO w / prepared statements

注册

使用以下方法清除所有输入:

  • 修剪
  • 的stripslashes
  • 用htmlspecialchars

他们必须通过preg_match。

用户必须选择帐户名称和昵称。帐户名用于登录,而昵称用于与论坛上的其他人通信。这两个名称不能相同,也不能存在于数据库中。

用户被问到一个随机问题,以检查它是否是人。

LOGIN

使用以下方法清除所有输入:

  • 修剪
  • 的stripslashes
  • 用htmlspecialchars

他们必须通过preg_match。

IP地址只能尝试每分钟登录一次,每小时总共登录3次,然后用户必须等待24小时再次尝试登录。

如果找不到帐户名称或密码错误,他们会收到相同的消息,可能是错误的。

成功登录后,将调用一个函数,该函数使用" 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ $ -_。," 之间的字符创建一个随机的32个字符长的字符串。然后,此函数将循环此字符串通过数据库中的所有用户行,直到它无法再找到相同的字符串,然后传递该字符串并将其放入帐户的名称(在SID1下),然后才能使用相同的函数再次调用并放置另一个32个字符长的字符串(在SID2下)。

每当用户登录时,都会生成一组新的字符串。

会话

$ _ SESSION(session_start)未使用。 $ _COOKIE是(#34;记住我")。所以,如果我通过将其称为会话或SID来使用错误的术语,我深表歉意。

放置在数据库中的两个32个字符的长字符串将合并并放在同名的cookie中。从那时起,这个64字符长的字符串是识别用户的唯一标准。每当用户需要许可来执行某些操作(例如查看特定论坛或编辑其帐户设置)时,这两个32个字符长的唯一ID(爆炸)用于调用数据库并返回用户的等级。换句话说,用户ID和帐户名永远不会用于调用数据库,只有用户cookie中的唯一ID。然而,在使用这些字符串来识别用户之前,它必须通过preg_match,以防万一有任何不可预知的方法来篡改cookie的输入(我不知道是否有或不,这就是为什么我决定采取这种预防措施)。

cookie将在4周内销毁,除非用户没有设置"记住我"登录后

每当用户注销时,通过将其设置为1年来销毁cookie。

POSTING

允许用户发布他们想要的任何UTF-8字符,并且这一个输入只需要在存储到数据库之前传递htmlentities。传递脚本似乎不会以这种方式工作。他们可以写<script>alert('hello');<script>,它会在帖子中显示,但脚本不会运行。但是,如果我尝试清除输出而不是输入,脚本将运行。虽然,我可能不知道传递脚本的所有方法。所以,如果你能想到任何一个,请启发我,或者我只需要找到困难的方法。

我已经做到这一点,如果用户在帖子中写了一个网址,网址会自动放入&#34; a href&#34;。同样,图片也被放入&#34; img&#34;,YouTube视频被放入&#34; iframe&#34;。下一步是每个帖子只允许一个图像和一个YouTube视频,但我想我必须找出缓存是如何工作的,因为我的网站的响应时间从0.25秒变为超过3秒帖子包含外部图片/视频。我可能需要检查外部图像是否真的是图像,以避免隐藏在图像中的恶意代码,但我还不确定它是如何工作的;也许找出URL是否是图像的最佳方法是检查它是否是图像所以我可能不得不重写所有图像。

除了SSL之外,我不太确定我还能做些什么来保护我的网站,或者我的登录/注册/会话/发布方法是否足够好。

如果我错过了什么,请告诉我。

1 个答案:

答案 0 :(得分:1)

我没有采取你采取的安全措施的十分之一,但我拿了一个你不提的。您似乎不使用SSL,因此您的ID /密码在登录时以可读状态传递。这意味着他们可以被倾听(不知道怎么样,我自己也不能这样做,但实际上他们可以这样做)。

我使用的一个简单易用的技巧:
- 我的登录表单是由一个php脚本构建的,它将一个javascript变量(var salt)设置为一个随机值(比如说当前时间戳的sha1())
- 此值通过会话变量(或您的配置中的cookie)记忆服务器端 - 当用户提交登录表单时,javascript函数(简称crypt_pw())称为
- 此crypt_pw()函数在实际提交之前将密码(1)的sha1的sha1连接到之前描述的salt - 服务器收到此sha1(sha1(密码)+ salt)并将其与sha1((db storage password).salt)进行比较。
(1)存储在DB中的密码已经过哈希处理,因此无法直接读取。
类似的东西:

$query="select count(*) from user_table where login='$login'
and sha1(concat(password,'salt'))='$jsCryptedBeforeSendPassword'"

整个过程比解释要容易得多,它确保没有人可以对任何人做任何事情&#34;嗅探&#34;密码:从任何其他计算机发送,会话变量不存在服务器端以允许比较密码。即使是在同一台计算机上的同一个客户端,但是在不同的时间,登录表单将使用另一个盐值构建php,因此无法重复使用嗅探的加密密码。

顺便说一句,我现在无法检查代码,也许我也会对登录值进行加密,而不仅仅是密码。 如果您已经连接https,这一切都无用。

相关问题