【问题标题】:Why does this index string clear the $_SESSION array? [duplicate]为什么这个索引字符串会清除 $_SESSION 数组? [复制]
【发布时间】:2017-02-14 08:28:55
【问题描述】:

我发现了一些奇怪的行为 - 我很感兴趣 - 任何人都可以对此有所了解..?

概述

今天早上花了一些时间寻找导致$_SESSION 数组为空的错误的原因。最终找到了它的底部,发现在为$_SESSION 变量之一定义索引时,& 被用于连接而不是.。仅当两个特定字符串为&ed 时才会中断,其他字符串导致无意义的键但$_SESSION 没有为空。

这是在 PHP5.5.9-1ubuntu4.20 和本地 PHP5.6.15 上运行的。

自己试试吧!

使用下面的示例代码,

  1. 运行set-session.php
  2. 运行 check-session.php - 一切正常
  3. 运行 break-session.php - 到目前为止还不错...
  4. 再次运行 check-session.php - $_SESSION 现在为空!

示例代码

set-session.php

session_start();

$_SESSION = [
   'colour' => 'blue',
   'shape'  => 'round',
   'size'   => 'medium'
];

check-session.php

session_start();

echo '<pre>';
print_r($_SESSION);

break-session.php

session_start();

$killer_string = 'Admin_CH_1_' & '101_';
$_SESSION[$killer_string] = null;

echo '<pre>';
print_r($_SESSION);

我的猜测

我猜按位运算的结果是一个字符串,在本例中为$killer_string,这会导致PHP 在尝试将$_SESSION 数组存储在服务器上时生气。奇怪的是,$killer_string 在用作 $_SESSION 中子数组的键时不再是杀手。

想法?

我知道代码实际上没有意义,所以 PHP 没有问题。但是,我很好奇幕后实际发生了什么以及导致这种情况的原因......

干杯!

【问题讨论】:

  • var_dump($killer_string);了吗?产量☺ !I
  • 您使用的是什么 PHP 版本?我刚刚用 5.6.25 进行了测试,$killer_string 被设置为一个数组键,其字符串类似于@AbraCadaver
  • 我的结果与 php-7 中的@MichaelBerkowski 相同
  • 用我得到的版本更新了问题。
  • 错误跟踪器中也有一些错误报告报告了此问题。

标签: php


【解决方案1】:

这是一个简化的测试用例 (see it in action):

<?php
header('Content-Type: text/plain');
ob_start();

session_start();
$_SESSION = [
    'colour'               => 'blue',
    'shape'                => 'round',
    'size'                 => 'medium',
    //'Admin_CH_1_' & '101_' => 'Gone',
    chr(0x01) . chr(0x20) . chr(0x21) . chr(0x49) => 'Gone',
];
var_dump($_SESSION);
session_write_close();

session_start();
var_dump($_SESSION);
ob_end_flush();

如果您检查会话文件,您会发现它的字节数为零。

到目前为止,我最好的猜测(直到有人更聪明地与特定内部共享 PHP github 存储库的链接)是您无意中推动了会话序列化代码的限制。此类代码假定键是非二进制字符串。有一定的验证(纯数字键会触发跳过数字键通知),但它并没有涵盖所有可能的格式错误的输入。在某些时候它会崩溃。

这得到了改变序列化方法修复问题的支持:

ini_set('session.serialize_handler', 'php_serialize');

session.serialize_handler documentation我们可以阅读:

较旧的序列化处理程序无法存储数字索引或字符串索引 在$_SESSION 中包含特殊字符(| 和!)。采用 php_serialize 避免数字索引或特殊字符错误 脚本关闭。默认为php

【讨论】:

  • 感谢您的回复。原来这种行为已经存在,只是搜索起来很棘手!
猜你喜欢
  • 2021-10-03
  • 2021-12-09
  • 1970-01-01
  • 2019-09-26
  • 2019-10-12
  • 2012-07-26
  • 1970-01-01
  • 2020-03-22
  • 2018-08-21
相关资源
最近更新 更多