这是一种安全的Session变量使用方法吗?

4
我使用$_SESSION['name']来处理页面之间的数据。我主要用它来在页面之间保持用户登录状态。在每个页面中,我检查$_SESSION['logged_in']是否为真。如果为真,则保持用户登录。否则,执行其他操作。
以下是我如何处理会话的基本示例:
<?php

session_start();

if($_SESSION['logged_in'])
{
   //show control panel list
}
else
{
     //show login box. Once user logs in. Once user logs in,
     //fetch userID, username, etc from database. Also set 
     //$_SESSION['logged_in'] = true.
}

?>

在代码中间,我做了如下操作:

SELECT * FROM User WHERE userID = $_SESSION['userID'];

我不确定 $_SESSION['userID'] 是否对用户可见。如果它是可访问的,那么页面将受到威胁,因为用户可以手动更改 userID 并访问他/她想要的其他账户。

我并不熟悉安全方面知识。请给出建议!我该怎么做?

注意:我正在尝试尽可能简化代码。目前还没有涉及面向对象编程。


用户可以操作他们的cookie,但不能操作他们的会话数据,这就是简短的答案...我认为你做得很好。也许应该评估一下非登录用户是否应该被踢出到单独的登录页面并退出,以避免脚本继续运行。 - Teson
长答案:您的用户只提供了一个 session_id,它通过 cookie 或 get 变量传递。此标识符允许 PHP 查找该用户的会话,该会话存储在您的服务器上(默认情况下为文件)。PHP 读取会话数据并使用数据填充 $_SESSION 超级全局变量。用户无法直接访问会话数据,因此在其中存储敏感数据是可以的。 - Carl Zulauf
可能是PHP会话变量有多安全?的重复问题。 - Alexander O'Mara
4个回答

4

您的代码容易受到会话固定和会话劫持攻击。请参考http://phpsec.org/projects/guide/4.html获取更多信息。

当您构建更大、更复杂的应用程序时,还要注意如何安全地处理用户注销和处理其他与会话相关的方面,例如特权升级。安全地处理会话和登录是一项棘手的任务。

实现安全认证是困难的。除非您将其作为学术性练习,否则我强烈建议使用您的框架提供的库,如果你很幸运拥有一个好的库的话。

同时,您还需要考虑以下事项:

  • 不允许会话ID被强制。[会话固定]
  • 当权限或凭据发生更改(例如因为用户现在已经登录或退出)时,立即使会话无效并开始一个新的会话。
  • 提供注销功能,并确保在注销时使会话无效。
  • 将会话cookie设置为HttpOnly——最好要求HTTPS并仅将cookie设置为安全的。
  • 考虑将会话有效性限制为包括检查帮助匹配用户的其他信息,例如user-agent。[会话劫持]
  • 始终在非使用后过期会话,并且不要通过重新连接用户到他们的旧HTTP会话来实现“保持登录状态”。
  • 确保在会话无效时销毁所有与会话相关的数据,无论其存储在何处。即使新用户偶然获得了此前已被分配的会话ID,该新会话也不得访问已针对该会话ID设置的任何会话数据。

2

$_SESSION是服务器端的超级全局变量之一。它不可被用户访问,也不会以任何方式从服务器传输。


1

是的,那基本上就是正确的想法。

这里有几个资源可能会有所帮助,无论是理解会话安全性还是安全编程一般:

http://phpsec.org/projects/guide/4.html http://phpsec.org/projects/guide/


1

这很不错,以下是一些有关会话管理的其他提示:

  1. 不要接受来自GET/POST变量的会话标识符: 不建议在URL(查询字符串、GET变量)或POST变量中使用会话标识符,因为它简化了攻击。可以轻松地在表单上设置GET/POST变量。

  2. 在每个请求上重新生成SID: 在PHP中使用session_regenerate_id()。每当用户的访问级别发生更改时,需要重新生成会话标识符。这意味着,尽管攻击者可能会欺骗用户接受已知的SID,但当攻击者尝试重新使用SID时,该SID将无效。


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