【问题标题】:PHP Serialize Successful, Unserialize FailurePHP序列化成功,反序列化失败
【发布时间】:2011-12-02 14:48:03
【问题描述】:

我的 PHP 代码序列化,但没有反序列化,可能是什么问题?

$serializedColumns = serialize($columnNames);

我有以下生成的 html,我将序列化的字符串存储到隐藏字段中:

<input id="columns_hidden" name="columns" type="hidden" value="a:3:{i:0;s:8:&quot;Username&quot;;i:1;s:8:&quot;Password&quot;;i:2;s:11:&quot;AccessLevel&quot;;}">

请求被发送到“AddData.php”,我的反序列化代码如下:

$columns =  unserialize($_REQUEST['columns']);

当我在$columns 上调用print_r 时,它返回一个空白字符串。

当我在$_REQUEST['columns'] 上调用print_r 时,它返回:

a:3:{i:0;s:8:\"Username\";i:1;s:8:\"Password\";i:2;s:11:\"AccessLevel\";}

【问题讨论】:

  • print_r($_REQUEST['columns']); 在说什么?
  • {前面开头的:不见了:a:3{是错的,必须是a:3:{,但是你不应该使用serialize来做你的工作。 Explanation and alternatives.
  • 这是一个极端的安全漏洞。

标签: php forms serialization


【解决方案1】:

如果您对该列使用 VARCHAR,请尝试将您的 MySQL 列更改为 TEXT。

【讨论】:

    【解决方案2】:

    当您的数据发布到 PHP 时,看起来好旧的魔术引号在所有分隔引号之前注入 \。在解码/反序列化之前,您必须先取消转义(斜杠)。

    【讨论】:

      【解决方案3】:

      这实际上是一条评论,但我把它放在这里是为了引起更多注意:不要那样做

      为什么? - 每当你 unserialize 盲目地请求提供数据时,PHP 所做的比你想象的要多。这可能会创建对您的应用程序很危险的对象,而您不能对此采取任何措施。

      可以使用 DOM 编辑器或 JavaScript 轻松编辑和操作隐藏的输入,以包含有害代码,或者可以针对您的网站触发恶意请求,从而迅速将其关闭。

      替代方案 - 改为使用您可以更轻松地处理的某种形式的数据,例如,使用 json_encode / json_decode 或经典的 implode / explode

      $serializedColumns = implode(',', $columnNames);
      

      $columns =  explode(',', $_REQUEST['columns']);
      

      因为它是静态数据处理,所以更加安全和理智。

      【讨论】:

      • 谢谢,我决定使用 json_encode 和 json_decode。
      【解决方案4】:

      看来您正在通过 htmlspecialchars 传递序列化结果。这将破坏序列化的数据。使用不同的编码方法使其可以安全地用作 html 属性值,即base64_encode:

      <?php
      $serializedColumns = serialize($columnNames);
      ?>
      
      <input id="columns_hidden" name="columns" type="hidden" value="<?php echo base64_decode($serializedColumns) ?>">
      

      然后,在您的处理脚本中:

      $columns =  unserialize(base64_decode($_REQUEST['columns']));
      

      【讨论】:

      • 为什么会破坏序列化数据?
      • 为什么?根据问题中给出的数据,导致此问题的不是字符串长度,而是缺少:。但是,我看不出htmlspecialchars 应该如何造成这种情况。查看更新后的问题。
      【解决方案5】:

      &amp;quot; 可能会妨碍序列化,因为 ; 没有被转义。

      您可以base64_encode 该值并在之后对其进行解码:

      $serializedColumns = base64_encode(serialize($columnNames));
      

      $columns =  unserialize(base64_decode($_REQUEST['columns']));
      

      【讨论】:

      • 请求变量中没有 html-entities。
      猜你喜欢
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多