PHP __PHP_Incomplete_Class 对象,其中包含我的 $_SESSION 数据

2022-08-30 10:57:41

我有一个站点设置,在页面加载时,将所有用户提交的字符串转换为SafeString对象。对于那些不熟悉SafeString的人来说,它基本上迫使用户回显出经过清理的数据,以防止XSS等等。

无论如何,有一个问题。我的 $_SESSION 数组正在填充 .根据我所读到的内容,这是由于在会话之前没有初始化类,然后在会话中存储类对象。__PHP_Incomplete_Class Object

这是我的代码:

require_once __WEBROOT__ . '/includes/safestring.class.php'; 

$temp = array
(
   &$_SERVER, &$_GET, &$_POST, &$_COOKIE,
   &$_SESSION, &$_ENV, &$_REQUEST, &$_FILES,
   &$HTTP_SERVER_VARS, &$HTTP_GET_VARS,
   &$HTTP_POST_VARS, &$HTTP_COOKIE_VARS,
   &$HTTP_POST_FILES, &$HTTP_ENV_VARS
); 

function StringsToSafeString(&$array)
{
   foreach ($array as $key => $value)
   {
      if (is_string($array[$key]))
      {
         $array[$key] = new SafeString($value);
      } 

      if (is_array($array[$key]))
      {
         StringsToSafeString($array[$key]);
      }
   }
}

StringsToSafeString($temp);

unset($temp);

我想不出一种方法来重写这个问题,可以解决这个问题:/

有什么想法吗?


答案 1

访问 时,您不仅要更改当前脚本从会话中读取的数据的副本,还要将 SafeString 对象写回活动会话。$_SESSION

但是,将自定义对象放在会话中是狡猾的,我通常会尽量避免这种情况。为了能够做到这一点,你必须在调用之前定义有问题的类;如果不这样做,PHP 的会话处理程序将不知道如何反序列化该类的实例,并且你最终会得到 .session_start__PHP_Incomplete_Class Object

因此,请避免在会话中嬉戏。如果必须采用此方法,请将数据从 复制到本地数组中。但是,我不得不说,我认为SafeString的整个想法是危险且不可行的。我不认为这种方法会是无懈可击的。原始文本字符串是否“安全”与它的来源无关,它是你如何为目标上下文编码它的属性。$_SESSION$mysession

如果从其他源(如数据库或文件)获取另一个文本字符串,或者在脚本本身中计算,则需要与来自用户的字符串完全相同的处理:需要对其进行 ed。无论如何,你都必须写那个逃生;安全绳对你一无所获。如果需要将字符串发送到其他目标格式,则需要不同的转义。htmlspecialchars

您不能将所有字符串处理问题封装到一个方便的框中,而再也不考虑它们;这不是字符串的工作方式。


答案 2

我知道这个问题已经很多年了,但我发布了我的答案,因为上面的答案实际上都没有向OP解释实际上出了什么问题。

PHP 使用内置的序列化和非序列化方法序列其会话。PHP 的序列化能够序列化 PHP 对象(也称为类实例)并将其转换为字符串。当您取消序列化这些字符串时,它会将它们转换回具有这些值的相同类。具有一些私有属性并希望对其进行编码/解码或在其序列化/反序列化中执行复杂操作的类实现 Serializable 类,并向该类添加序列化和非序列化方法。

当 PHP 的反序列化尝试取消序列化类对象,但类名未声明/必需时,它不会发出警告或引发异常,而是将其转换为 的对象。__PHP_Incomplete_Class

如果不希望将会话对象转换为 ,则可以通过在调用session_start之前要求类文件或注册自动加载函数来执行此操作。__PHP_Incomplete_Class


推荐