注册,登录,会话和发布安全措施 [英] Registration, login, session and posting security measures

查看:75
本文介绍了注册,登录,会话和发布安全措施的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次向任何人提出有关Web开发的问题.尽管其他人之前曾提出过许多类似的问题,但我决定提出这个问题的原因是,由于其他人过去收到的答案数量庞大且主观性强,因此我对如何处理它感到困惑和怀疑.

This will be the first time I ask a question to anyone in regard to web development. The reason why I decided to ask this question, spite many similar questions asked before by others, is because the answers that others received in the past came in great quantity and subjectivity, so I became confused and doubtful as to how to approach it.

我意识到可以通过不同的方式来解决这个问题,这就是为什么我的问题可能引起一些讨论,但是如果有任何讨论,我希望每个人都记住我的问题的具体内容:我不是要问什么是最安全的方法,但是我的方法是否绝对安全;我的目标是提高流行论坛的安全性,而不是进行金钱交易的大型公司网站(如Amazon或Paypal)的安全性.

I realize that there are different ways to approach this, which is why my question may cause some discussion, but I would like everyone to remember the specifics of my question, should any discussion arise: That I'm not asking for what is the most secure approach, but whether my approach is secure at all, or not; I'm aiming for the security level of popular forums, not large company websites such as Amazon or Paypal where money transactions take place.

我用什么

  • PHP 5.5 for password_hash
  • 带有准备好的语句的PDO

注册

使用以下命令清除所有输入:

All inputs are cleaned with the following:

  • 修剪
  • 带斜杠
  • html特殊字符

,并且必须通过preg_match.

and they must pass through preg_match.

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

The user must choose an account name and a nickname. The account name is used to login with, whereas the nickname is used to communicate with others on the forum. These two names cannot be identical with each other, nor can they already exist in the database.

向用户询问一个随机问题,以检查它是否是人类.

The user is asked a random question to check if it's human or not.

登录

使用以下命令清除所有输入:

All inputs are cleaned with the following:

  • 修剪
  • 带斜杠
  • html特殊字符

,并且必须通过preg_match.

and they must pass through preg_match.

在用户必须等待24个小时才能再次尝试登录之前,一个IP地址只能每分钟尝试一次登录,每小时总计尝试登录3次.

An IP address can only attempt to log in once per minute, to a total of 3 times per hour, before the user will have to wait for 24 hours to attempt to log in again.

当找不到帐户名或密码错误时,他们会收到相同的消息,可能是错误的.

When account name is not found, or password is wrong, they receive the same message that either could be wrong.

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

Upon successful login a function is called, which creates a random 32 character long string, using characters ranging between "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$-_.,". This function will then loop this string through all the user rows in the database until it can no longer find an identical string, then pass the string and place it in the account's name (under SID1), before the same function is called again and another 32 character long string is placed (under SID2).

每当用户登录时,都会创建一组新的字符串.

Whenever the user logs in, a new set of strings are made.

会议

不使用$ _SESSION(session_start). $ _COOKIE是(用于记住我").因此,对于将会话或SID称为错误术语,我深表歉意.

$_SESSION (session_start) is not used. $_COOKIE is (for "remember me"). So I apologize if I'm using the wrong terminology by referring to it as a session or as a SID.

将两个放置在数据库中的32个字符长的字符串合并,并以相同的名称放置在cookie中.从那时起,这64个字符长的字符串就成为了识别用户的唯一措施.每当用户需要执行某项操作(例如查看特定论坛或编辑其帐户设置)的权限时,就会使用这两个32个字符长的唯一ID(爆炸)来调用数据库并返回用户的排名.换句话说,永远不会使用用户ID和帐户名来调用数据库,而仅使用用户Cookie中的唯一ID.但是,在使用这些字符串标识用户身份之前,必须先通过preg_match,以防万一有任何无法预料的方式篡改cookie中的输入(我不知道是否存在,这就是为什么)我决定采取这种预防措施).

The two 32 character long strings that were placed in the database are merged and placed in a cookie under the same name. This 64 character long string is from then on the only measure of identifying the user. Whenever the user needs permission to do something, such as viewing a particular forum, or editing his account settings, these two 32 character long unique IDs (explode) are used to call the database and return the user's rank. In other words, the user id and account name is never used to call the database with, only the unique IDs in the user's cookie is. Before these strings are used to identity the user, however, it has to pass through a preg_match, just in case there's any unforseen way of tampering with the input from the cookie (I don't know whether there is or not, which is why I decided to take that precaution).

除非用户在登录时未设置记住我",否则cookie设置为在4周内销毁.

The cookie is set to destroy in 4 weeks, unless the user did not set "remember me" upon login.

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

Whenever the user is logged out, the cookie is destroyed by setting it to -1 year.

发布

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

Users are allowed to post any UTF-8 character they want, and this one input only has to pass through htmlentities before it is stored in the database. Passing scripts does not seem to work this way. They can write <script>alert('hello');<script> and it will appear that way in the post but the script will not run. But if I attempt to clean the output, instead of input, the script will run. Though, I may not know all the ways to pass scripts. So, enlighten me if you can think of any, or maybe I'll just have to find out the hard way.

我这样做的目的是,如果用户在其帖子中写一个URL,则该URL将自动放入"a href"中.同样,将图片放入"img",将YouTube视频放入"iframe".下一步是每个帖子只允许一张图片和一个youtube视频,但是我想我必须找出缓存的工作原理,因为只要帖子包含外部图片,我的网站的响应时间就会从0.25秒缩短到3秒以上/视频.我可能必须检查外部图像是否真的是图像,以避免隐藏在图像中的恶意代码,但是我不确定这是如何工作的.找出URL是否是图像的最好方法就是检查它是否是图像,因此我可能不得不重写所有图像.

I've made it so that if the user writes an URL in their post the URL is automatically put into an "a href". Likewise, images are put into "img", and YouTube videos are put into "iframe". Next step is to only allow one image and one youtube video per post, but I think I'm going to have to find out how caching works because my site's response time went from 0.25 seconds to over 3 seconds as soon as posts contained external images/videos. I will probably have to check external images whether they're really images or not to avoid hostile code hiding in the image but I'm not sure yet how that works; maybe the best way to find out whether the URL is an image or not is to check whether it's an image so I'll probably have to rewrite all of it.

除了SSL之外,我不太确定该如何保护我的网站,或者我的登录/注册/会话/发布方式是否足够好.

Except for SSL, I'm not quite sure what else I can do to secure my site, or whether my login/registration/session/posting approach is in any way good enough.

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

Please let me know if I've missed something.

推荐答案

我没有采取您采取的十分之一安全措施的一半,但我没有采取您未提及的措施.您似乎没有使用SSL,因此您的ID/密码在登录时以可读状态通过管道.这意味着可以听他们的声音(不知道怎么做,我自己做不到,但实际上可以).

I'm not taking half of a tenth of the security measures you take, but I take one you don't mention. You seem not to use SSL, so your id/password pass through the tubes in a readable state at login time. This means they can be listened to (no idea how, I couldn't do it myself, but they actually can be).

对此我使用了一个简单的技巧:
-我的登录表单由php脚本构建,该脚本将javascript变量(var salt)设置为随机值(例如,当前时间戳记sha1())
-该值通过会话变量(或配置中的cookie)存储在服务器端 -当用户提交登录表单时,将调用javascript函数(例如crypt_pw())
-此crypt_pw()函数在实际提交
之前,将密码(1)的sha1与先前描述的salt连接在一起 -服务器收到此sha1(sha1(password)+ salt)并将其与sha1((db存储的密码).salt)进行比较.
存储在数据库中的(1)密码已经进行了哈希处理,因此无法直接读取.
像这样:

A little and easy trick I use against that:
- my login form is constructed by a php script, which sets a javascript variable (var salt) to a random value (lets say sha1() of current timestamp)
- this value is memorized serverside through a session variable (or maybe a cookie in your configuration) - when user submits the login form, a javascript function (lets say crypt_pw() ) is called
- this crypt_pw() function does a sha1 of the sha1 of the password (1) concatenated to the previously described salt before actually submiting
- the server receives this sha1(sha1(password)+salt) and compares it with a sha1((db stored password).salt).
(1)password stored in DB is already hashed so that it's not directly readable.
Something like:

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

整个过程比说明要容易得多,并且可以确保任何人都无法使用任何嗅探到的"密码来做任何事情:从任何其他计算机发送来的会话变量都不会在服务器端存在以允许比较密码.即使来自同一台计算机上的同一客户端,但在不同的时间,登录表单也将使用另一个盐值来构造php,因此无法重复使用嗅探到的加密密码.

The whole thing is much easier to do than to explain, and it insures that nobody can do anything with any "sniffed" password: sent from any other computer, the session variable won't exist serverside to allow comparing password. Even from the very same client on the very same computer but at a different time, the login form will be php constructed with another salt value so the sniffed crypted password can't be reused.

顺便说一句,我现在无法检查代码,也许我也添加和散列了登录值,而不仅是密码1. 当然,如果您已连接https,这将毫无用处.

Btw, I can't check the code right now, maybe I salt-&-hash the login value too, not only the password one. This is all unuseful if you're https connected, of course.

这篇关于注册,登录,会话和发布安全措施的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆