PHP会话有多安全?

38

我主要是一名C++程序员,但我正在尝试学习一些PHP。

显然,实现Web用户会话的方法是使用$_SESSION变量将用户的登录ID存储在cookie中。

是否有人可以修改他们的cookie以获得不同的权限或登录为另一个用户?

看起来这个身份验证机制就像让用户将他们的ID存储在文件中-然后只是相信他们不去改变它。

是否有什么防止这种情况的措施呢?

谢谢!


4
这个话题有整本书在讨论。 - user557846
2
http://phpsec.org/projects/guide/4.html,http://stackoverflow.com/questions/3641958/secure-sessions-cookies-in-php,http://stackoverflow.com/questions/5608764/purpose-of-php-sessions-and-cookies-and-their-differences,http://stackoverflow.com/questions/4110986/new-to-php-logins-and-sessions-is-this-safe-enough,https://dev59.com/zXM_5IYBdhLWcg3w4njb - Taz
2
可能是PHP会话变量有多安全?的重复问题。 - Alexander O'Mara
6个回答

70

PHP会话只有在您的应用程序使其安全时才是安全的。 PHP会话将为用户提供一个伪随机字符串(“会话ID”)以便他们进行身份识别,但如果该字符串被攻击者截获,攻击者可以冒充该用户。

该怎么做

这些信息摘自"PHP手册中的会话管理基础知识", 但是简化了一些内容。可能会漏掉一些东西。请务必仔细阅读。

  1. 始终使用 HTTPS

    • 防止攻击者读取会话ID cookie
  2. 启用 session.use_strict_mode:

  3. 启用 session.use_only_cookies 并禁用 session.use_trans_sid

    • 避免用户通过共享包含会话ID的URL而意外共享会话ID
    • 防止会话ID出现在 Referer 标头中
  4. 定期 重新生成会话ID在重新生成后不久使旧的会话ID失效

    • 如果攻击者使用另一个用户的会话ID,则重新生成将使用户或攻击者的会话无效,具体取决于哪个请求重新生成ID。然后,您可以跟踪某人尝试使用已经重新生成的会话的时间,并在那时使重新生成的会话无效。用户将能够登录,但攻击者(希望如此)将无法登录。
  5. 可选地在 $_SESSION 中跟踪与请求相关的其他信息(IP地址、用户代理字符串等)

    • 如果攻击者以某种方式获得会话ID,则可能可以在攻击者访问任何数据之前检测到入侵。但是,请记住,这可能会恶化用户体验。例如,当用户从移动网络切换到Wi-Fi时,IP地址可能会更改,并且当其浏览器自动更新时,用户代理字符串可能会更改。根据您的网站愿意处理的权衡调整要检查的数据。

1
很好的回答,但正如在另一个问题(被接受的答案,第三段)中所说,使用IP跟踪方法可能存在可用性问题,对吧? - AymDev
4
很遗憾,是的。由于从LTE切换到WiFi可能会更改IP地址。浏览器版本可能会因为自动更新而改变。我已经在答案中加入了一条注释,并添加了一些额外(并且更好的)建议来保护PHP会话。 - 0b10011
1
这应该是被接受的答案,因为它涉及到会话 ID 存储在用户端而不是服务器上的事实。 - dmuensterer
1
很好的答案,但还有一些额外的东西:1)设置短会话生命周期,2)设置会话cookie可用的路径,3)设置域名可用性,4)仅在安全的HTTP连接中使会话cookie可用 - DevelJoe
1
  1. 禁用不必要的跨站请求发送会话cookie。4)和5)将有助于更好地保护免受XSS和/或CSRF会话ID的偷窥攻击,这对我来说似乎是主要的危险之一。但即使所有这些都完成了,如果用户在会话期间将机器无人看管,仍然很容易被盗。最终,人类因素仍然是决定性的:D 是的,理想情况下,4)既涉及设置安全标志又涉及设置httponly标志。
- DevelJoe
显示剩余3条评论

24

不可以,会话是存储在服务器上的,用户无法访问。它用于在整个网站中存储信息,例如登录会话。

以下是使用示例:

<?php
session_start();
if (password_verify($_POST['password'], $hash)) {
    $_SESSION['auth'] = true;
}
?>

通过这种方式,可以跨站点访问会话以检查用户是否已被验证。

<?php
session_start();
if ($_SESSION['auth']) {
    echo "You are logged in!";
}
?>
用户无法编辑这些值,但是会话ID作为一个长的随机字符串通过cookie存储在计算机上。如果未经授权的用户获取了这些字符串,他们就可以访问该网站。

用户无法编辑这些值,但是会话ID以一串长的随机字符串的形式存储在计算机的cookie中。如果未经授权的用户获得了这些字符串,他们就可以访问该网站。


1
所以会话数据存储在服务器上。那就是我犯错的地方...谢谢。 - James
9
@James,"session information" 不会公开存储,但是 "session ID" 会。应该采取额外的预防措施来防止此类情况发生。请参见我的回答。 - 0b10011
你们现在可能更容易理解它,因为现在已经是2016年10月了,而这个问题是在将近4年前提出并活跃的。我的意思是,从安全角度来看,这个答案是错误的。 - MNR

7

如果这样做:

$_SESSION['user'] = $username;

然后$username不会直接存储在cookie中。相反,将生成一个唯一的会话ID并存储在cookie中。
您在$_SESSION中存储的信息仅存储在服务器端,永远不会发送到客户端。在客户端发出后续请求时,当您执行session_start()时,服务器将通过cookie中存储的ID加载会话数据。
它相对安全。唯一可能发生的事情是有人可能会截取会话ID,从而窃取真正用户的会话。但HTTPS可以防止这种情况发生。

1
实际上,HTTPS 只是使得在传输 Cookie 到用户时无法读取它。但是,如果攻击者某种方式获取了会话值,那么他们就可以获得访问权限。 - 0b10011

6
回答这个问题需要两个方面的方法:
  1. 对于大多数用例而言,PHP会话ID足够难以猜测。与其他广泛使用的系统相比,难度不大也不小。

  2. 仅信任会话cookie(仅存在会话cookie)从安全角度来看似乎不是很可靠,无论这个会话cookie来自哪里 - PHP还是其他地方。

因此,简而言之:PHP会话的安全性取决于您对它们的使用。对我所知道的任何基于会话cookie的系统都是如此。


1

既然你是C++程序员,那么你只需要知道客户端可见的会话只是指向不同地址空间(服务器)的指针,因此,无法从客户端模式访问该会话。


1
无论你在这个话题上得到什么答案,你最可能不会满意,因为关于这个话题有很多不同的观点。甚至还有整本书都是关于 PHP 会话和安全性的。
在这里你能得到的最好的答案可能是“会话的安全性取决于你想让它们有多安全”。更多的工作和更多的预防措施显然会使它们更安全,但是实现本身将消耗更多的时间。就像每件事情一样,你需要衡量什么程度的安全对你的需求来说足够安全。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接