网站登录的 PHP 会话安全

发布于 2024-10-07 23:51:53 字数 1435 浏览 0 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

清引 2024-10-14 23:51:53

最重要的是要记住:

不要相信客户端返回的任何内容

永远不要假设您获取的信息(在表单字段(甚至是隐藏字段)、会话变量等中)是有效的 - 使用服务器端逻辑来执行这些检查。

1.) 确保您的会话已加密。如果您使用 PHP 的内置会话,相关的熵(随机性)相对较高,所以应该没问题。

2.) 仅将会话 ID 存储在 cookie 中。任何其他信息都应该使用该 ID 在服务器上简单地关联起来。我见过很多情况,如果会话中的令牌“is_admin”= true,系统工程师就会确定某人是否是管理员。你显然可以看到这个问题。

有些人会抱怨这是一项昂贵的操作,但我建议为活动会话创建一个(我的)SQL 表。然后,当加载页面时,从表中提取关联数据并像处理任何其他数据一样处理它。某些框架(如 CodeIgnitor)通过更改一个配置项来为您完成此操作。

3.) 验证 IP - 在表中添加当前 IP 地址。如果当前 IP 与会话中的 IP 不匹配,则可能有人试图劫持。强制注销并终止。

4.) 对登录尝试进行限制。添加1秒sleep();每次登录的服务器端对于用户来说几乎是察觉不到的,但是对于自动化系统来说,它几乎不可能进行暴力登录。

5.) 注意“太健谈”。在登录时,您可能认为给出“用户名不存在”或“密码不正确”等描述性错误会很有帮助。这样的信息告诉黑客他们已经获得了有效的用户名 - 这使得黑客攻击速度更快。

6.) 少关心PHP和SSL的安全性,多关心你自己的逻辑。仅仅因为网站使用 SSL 并不能保证其安全。 SSL 与有效逻辑相结合可提供安全性。

7.) 如果您非常担心,您将需要转移到专用服务器。您服务器上托管的其他网站可能可以访问您的代码/数据库信息。他们可能没有像您一样采取必要的措施来保证安全。

8.) 不允许同时进行会话。这可以防止 MITM(中间人)攻击。 DB 会话方法的另一个优点是,如果两个客户端尝试同时从不同的 IP 登录,您可以强制注销。 DB 方法的另一个优点是它使您的系统可扩展(因为会话存储依赖于文件系统)。

9.) 使用 mysql_real_escape_string 而不是 add_slashes

如果您需要有关 PHP 安全性的更多信息,这是我的专长。请随时与我联系。

The most important thing to remember:

Don't trust ANYTHING that comes back from the client

Never assume that the information you are getting (in a form field (even hidden ones), session variables, etc.) are valid - use server-side logic to perform these checks.

1.) Make sure your session is encrypted. If you are using PHP's built-in sessions, the associated entropy (randomness) is relatively high, so you should be fine.

2.) ONLY store the session id in the cookie. Any other information should simply be associated on the server using that id. I've seen many cases where the system engineer determines if someone is admin if the token 'is_admin' = true in the session. You can obviously see the problem with this.

Some will complain that its an expensive operation, but I recommend creating a (my)SQL table for active sessions. Then, when the page is loaded, pull the associated data from the table and deal with it just as you would any other data. Some frameworks (like CodeIgnitor) do this for you by changing one configuration item.

3.) Validate against IP - in your table, add the current IP address. If the current IP doesn't match the one in the session, someone is probably trying to hijack. Force a logout and terminate.

4.) Place limits on login attempts. Adding a 1 second sleep(); server side on each login is virtually unnoticeable to the user, but for an automated system, it makes it virtually impossible to brute force logins.

5.) Watch being 'too chatty'. In a login, you may think it's helpful to give descriptive erros like 'username doesn't exist' or 'incorrect password'. Information like this tells a hacker that they have gotten a valid username - it makes hacking much faster.

6.) Be less concerned about the safety of PHP and SSL and more of your own logic. Just because a website uses SSL doesn't make it secure. SSL coupled with valid logic provides security.

7.) If you're SUPER concerned, you'll want to move to a dedicated server. It's possible that other websites hosted on your server could have access to your code/db information. They may not be taking the necessary steps to be as secure as you.

8.) Don't allow simultaneous sessions. This prevents a MITM (man in the middle) attack. Another advantage of the DB session approach is that you can force logouts if two clients are trying to login at the same time from different IPs. Yet another advantage to the DB approach is that it makes your system scalable (since session storage is filesystem dependent).

9.) Use mysql_real_escape_string instead of add_slashes

If you need more information on security with PHP, it's a speciality of mine. Feel free to contact me.

孤独陪着我 2024-10-14 23:51:53

1)使用https。登录页面至少必须使用 https 来保护用户的密码,但您应该考虑使整个经过身份验证的会话使用 https 来防止 cookie 被窃取。

要求 cookie 和 POST 数据包含正确的身份验证令牌。

您还可以考虑更改每个请求的身份验证令牌以防止会话固定。我建议您阅读如何防止跨站点请求伪造和其他类似的攻击。 OWASP 是一个很好的资源,可用于获取有关常见攻击以及如何缓解这些攻击的一般信息。

2) session_destroy 实质上使客户端的会话 cookie 失效,因此将来的请求将不会看到相同的会话数据。根据您的代码流程,您可以将 session_destroy 作为返回客户端之前执行的最后一件事,也可以手动取消设置 $_SESSION 超全局内容。

1) Use https. At a bare minimum the login page must use https to protect the user's password, but you should consider making the whole authenticated session use https to prevent cookie stealing.

Require both cookie and POST data to contain the correct authentication token.

You could also consider changing the authentication token on each request to prevent session fixation. I'd recommend you read up on how to prevent cross-site request forgery and other similar attacks. OWASP is a good resource for getting general information about common attacks and how to mitigate them.

2) session_destroy essentially invalidates the client's session cookie so future requests will not see the same session data. Depending on your code flow you can either make session_destroy the last thing you do before returning to the client, or you can manually unset the $_SESSION superglobal contents.

三生殊途 2024-10-14 23:51:53

这里要理解的重要一点是数据的存储位置 - 会话存储在服务器端,因此会话中的任何内容都不会发送到客户端,除非您有意将其包含在页面中。 Id 应该是随机的和非确定性的(即不可猜测的)。

这意味着您可以使用会话来存储密钥、ID 等,而不必担心用户能够找到它们是什么。

当您使用 session_destroy() 时,您将清除 Id 和变量之间的服务器端链接,从而导致会话不可用。客户端可能仍然拥有该 ID,但现在已无用。

如果不知道您实际在做什么,就不可能评论您的实现的安全性 - 但在会话中存储信息比直接在 cookie/表单数据中存储信息要好得多

编辑:重新您的 SSL 问题:

几乎支持 SSL每台现代服务器。 (您确实必须寻找不支持它的服务器)。 OpenSSL 是实现 SSL 的众多软件之一。

SSL 的基础知识如下: 您获得安装在服务器上的证书*。服务器使用此证书“签名”每个请求并加密客户端和服务器之间的传输。

*可以免费创建证书(Google“自签名证书”),但自签名证书通常会根据浏览器向用户发出警告/错误(因为没有隐含信任级别)。浏览器有一个“受信任”证书颁发者列表 - Verisign、Thawte 等等。这些是颁发证书的知名公司(通常收费)。

证书在一定时间内有效,并且具有不同的信任级别(例如,便宜的证书只需验证您的电子邮件地址是否正确,扩展验证证书仅在电话号码、护照、电子邮件地址和注册地址之后颁发已被发行人核实)。

EV 证书有一些优点(以及挂锁图标,您会看到绿色地址栏 - 请参阅 www.paypal.com)您需要确定这对您来说有多重要。

您应该联系您的主机询问是否/如何添加 SSL 证书。过去,这通常只适用于付费帐户,但现在它变得越来越普遍 - 所以如果你谷歌一下,你会想找到免费的 SSL 托管

The important thing to understand here is where the data is stored - sessions are stored server-side, so nothing in a session is ever sent to the client unless you intentionally include it in a page. The Id is supposed to be random and non-deterministic (ie un-guessable).

This means that you can use a session to store keys, Ids, etc and never worry about the user being able to find out what they are.

When you session_destroy(), you're clearing the server-side link between the Id and the variables rendering the session unusable. The client may still have the Id but it's now useless.

It's not possible to comment on how secure your implementation is without some idea of what you're actually doing - but storing information in sessions is far far better than directly in cookies/form data

EDIT: Re your SSL Question:

SSL Is supported on almost every modern server. (You really have to hunt for a server which doesn't support it). OpenSSL is one of many pieces of software which implement SSL.

The basics of SSL are as follows: You get a certificate* which is installed on the server. The server uses this certificate to "sign" every request and encrypt transmissions between client and server.

*Certificates can be created for free (Google " self-sign certificates ") but self-sign certificates usually give the user a warning/error depending on the browser (as there's no level of trust implied). Browsers have a list of "trusted" certificate issuers - Verisign, Thawte, and many more. These are well established companies who issue certificates (usually for a fee).

Certificate are valid for a certain time period and have varying levels of trust (eg cheap ones simply verify your email address is correct, Extended Verification certificates are only issued after phone numbers, passports, email addressess and registered address have been verified by the issuer).

There are some advantages to EV certificates (as well as a padlock icon, you get a green address bar - see www.paypal.com ) You'll need to decide how important that is to you.

You should contact your host to ask if/how you can add an SSL certificate. It used to be that this was usually only available for paid accounts but it's becoming far more common nowadays - so you're like to find free SSL hosting if you Google a bit

欢你一世 2024-10-14 23:51:53

每次用户提升权限级别(例如通过登录)时,我都会使用 session_regenerate_id() 。我知道您说过不能使用 SSL,但如果传输的信息非常敏感,您应该真正考虑一下。 session_regenerate_id() 与 SSL 结合提供了针对会话劫持的最强防御。如果您持有任何类型的敏感信息,您应该考虑免费托管是否真的能满足您的需要。

I would use session_regenerate_id() every time the user elevates their level of privilege (for example by logging in). I know you said you can't use SSL but you should really consider it if the info being transmitted is at all sensitive. session_regenerate_id() in combination with SSL provides the strongest defence against session hijacking. You should consider if free hosting is really giving you what you need if you're holding any sort of sensitive information.

荒路情人 2024-10-14 23:51:53

我正在编写一个登录脚本,并遵循@sethvargo 列出的每个步骤,如第一个和最重要的事情是检查数据是否由可信来源发送?为此,我通常会创建一个特殊的令牌并将其嵌入到类似这样的形式中。

hash('md5', 'special-phrase_' . time() . '_special-phrase');

在接收端,我运行一个循环,其工作原理如下。 1 分钟后该令牌将无法使用。

for ($i=0; $i<=60; $i++) {
    $phrase = hash('md5', 'special-phrase_' . (time() - $i) . '_special-phrase');
    if ($phrase == $token) {
        print('Request received from a trusted client.'); exit;
    }
}
print ('Request timeout!')!

我在登录系统中使用这种技术,这是处理可信数据的正确方法吗?请提出您的建议。
谢谢!

I'm working on a login script and followed every step listed by @sethvargo as described the first and the most important thing is to check weather the data is sent by a trusted source or not? Fir this purpose I usually do is that I create a special token and embed it in the form it's like something like this.

hash('md5', 'special-phrase_' . time() . '_special-phrase');

And on the receiving side I run a loop which works like this. The token will be of no use after 1 minute.

for ($i=0; $i<=60; $i++) {
    $phrase = hash('md5', 'special-phrase_' . (time() - $i) . '_special-phrase');
    if ($phrase == $token) {
        print('Request received from a trusted client.'); exit;
    }
}
print ('Request timeout!')!

I'm using this technique in my login system, is this right way to deal trusted data? Please give your suggestions.
Thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文