【问题标题】:Problem with unserializing a PHP class and with gzinflate反序列化 PHP 类和 gzinflate 的问题
【发布时间】:2011-08-01 19:41:58
【问题描述】:

我正在尝试序列化一个类(用户)并将其作为 GET 变量传递到下一页。

这是我的测试代码:

$usr->getByLoginPass($db,"perf@stud.de","a32636ba1c7875b19c6f32121078c2da0be6f857");
$serial = $usr->serialize();
$handle = fopen("http://localhost/newClassSite/utests/userSerializationTest.php?data=$serial", "rb");
$contents = "";
while (!feof($handle)) {
    $contents .= fread($handle, 8192);
}
fclose($handle);
if(strpos($contents,"Perfect") === false) {
    echo"$contents<br>";
    echo"Problem with serialization testUser.test:16" . $usr->getLastError() . "<br>";
}

这是 userSerializationTest.php 中的代码:

$data = $_GET['data'];
echo"5: $data<br>";
include('../user.inc');
$usr = new User();
$usr->deserialize($data);
$usr->printUser();

这是类中的代码:

public function serialize() {
    $serial = serialize($this);
    $df = gzdeflate($serial);
    $b64 = base64_encode($df);
    $ue = urlencode($b64);
    echo "<font face='Courier New'>1: $serial<br><br>2: $df<br><br>3: $b64<br><br>4: $ue<hr><br>";
    return($ue);
}

public function deserialize($data) {
    $ud = urldecode($data);
    $u64 = base64_decode($ud);
    $gf = gzinflate($u64);
    $us = unserialize($gf);
    echo"6: $ud<br><br>7: $u64<br><br>8: $gf<br><br>9: $us<hr><br>";
}

这是输出:

1: O:4:"User":9:{s:12:"UseruserID";s:1:"9";s:15:"UserstudentID";s:3:"007";s: 11:"用户邮箱";s:12:"perf@stud.de";s:10:"Usersha1";s:40:"a32636ba1c7875b19c6f32121078c2da0be6f857";s:11:"用户名";s:7:"完美"; s:11:"用户名";s:7:"学生";s:12:"用户状态";s:2:"OK";s:17:"用户中间名";s:0:"";s:15 :"UserlastError";s:0:"";}

2: ]M„=0@[hŸº0&ÖÄxÊOlÒVte¼»”†ÆºðÍ0o †ÐÝi‹ ‚·Bm¦ófËé€vªâ^$ÍùQéÁÏrc $t/Ú.¢÷ÒÖì§+[¥#ÃKÎC‰äˆŒ²Œ5,H^ò ¢!•d&£„ÌKI•Àf¦,þ™Aô1”º†9Zúµ¡û1ÜæÚ©Wz‹ð£›X@õ9Š

3:XZBNDsIgFIQ9CwcwQFtonxsXujAm1sR4AMpPbNJWA3RlvLuUhsa6gfDNMG + ghhzQ3WmLoIK3A0IBbabzZgzL6YB2gQGq4l4kzflR6cHPcgYIYx4NJBl0L9ouopD30tbspytbpSPDS85DkInkgYiMsow1gkhe8qIhlWQmo4QSzEtJlcCNZqYs / gaZQfQxlAO6hjla + RWH + zHc5tqpV3qL8KObWED1OYo8iX2rVKcvISI6Qs31R3TC + aO1T7uony8 = P>

4:XZBNDsIgFIQ9CwcwQFtonxsXujAm1sR4AMpPbNJWA3RlvLuUhsa6gfDNMG%2BghhzQ3WmLoIK3A0IBbabzZgzL6YB2gQGq4l4kzflR6cHPcgYIYx4NJBl0L9ouopD30tbspytbpSPDS85DkInkgYiMsow1gkhe8qIhlWQmo4QSzEtJlcCNZqYs%2FgaZQfQxlAO6hjla%2BrWh%2BzHc5tqpV3qL8KObWED1OYo8iX2rVKcvISI6Qs31R3TC%2BaO1T7uony8%3D P>

5:XZBNDsIgFIQ9CwcwQFtonxsXujAm1sR4AMpPbNJWA3RlvLuUhsa6gfDNMG + ghhzQ3WmLoIK3A0IBbabzZgzL6YB2gQGq4l4kzflR6cHPcgYIYx4NJBl0L9ouopD30tbspytbpSPDS85DkInkgYiMsow1gkhe8qIhlWQmo4QSzEtJlcCNZqYs / gaZQfQxlAO6hjla + RWH + zHc5tqpV3qL8KObWED1OYo8iX2rVKcvISI6Qs31R3TC + aO1T7uony8 = P>

警告:gzinflate() [function.gzinflate]:第 117 行 C:\wamp\www\newClassSite\user.inc 中的数据错误 6:XZBNDsIgFIQ9CwcwQFtonxsXujAm1sR4AMpPbNJWA3RlvLuUhsa6gfDNMG ghhzQ3WmLoIK3A0IBbabzZgzL6YB2gQGq4l4kzflR6cHPcgYIYx4NJBl0L9ouopD30tbspytbpSPDS85DkInkgYiMsow1gkhe8qIhlWQmo4QSzEtJlcCNZqYs / gaZQfQxlAO6hjla RWH zHc5tqpV3qL8KObWED1OYo8iX2rVKcvISI6Qs31R3TC aO1T7uony8 = P>

7: ]M „=0@[hŸº0&ÖÄxÊOlÒVte¼»”†ÆºðÍ0h!‡47Zbè ÀЀ[i¼Ùƒ2ú@j¸—‰3~Tzps܂ǃI]ö‹¨¤=ôµ»)ÊÖéHðÒóä"y b#,£'¼¨ˆeY ¨á³Òep#Y©‹?¦P}eV«ZÇs›j¥] ê/ÂŽmaÔæ(ò%öRœ¼„ˆé7ÕÓ £µO»¨Ÿ/

8:

9:

用户: 编号:-1 标识: 电子邮件: 经过: 名称: 名字: 状态: 中间:

我希望最后填写这些字段。
为什么 gzinflate 失败了?
我在这里错过了什么?

【问题讨论】:

  • 为什么不简单地把它存储在会话数组中呢?
  • 你真的不应该那样做。一旦知道类内容,就可以轻松伪造用户对象。
  • 当然,这不安全。在这一点上,我只想让它工作,以便我可以传递对象。
  • 哇!我自己很擅长变态,但你打败了我!

标签: php class serialization gzip


【解决方案1】:

您的deserialize() 函数中不需要urldecode()。 PHP 在构建 $_GET 数组时已经处理了所有这些问题。这很可能是问题所在 - 您对数据进行了双重解码,并且偶然地,某些 gzdata 具有最终看起来像合法 urlencoded 数据的字符序列。

还有,为什么要使用&lt;font&gt; 标签来输出调试数据?使用&lt;pre&gt;。它旨在以固定宽度的字体输出文本。

【讨论】:

  • 太好了,我快到了 ;) 删除 urldecode 再次给了我正确的数据。
  • 不幸的是,我不知道如何恢复对象。我有以下内容:code public function deserialize($data) { $u64 = base64_decode($data); $gf = gzinflate($u64); unserialize($gf); echo"6: $u64&lt;br&gt;&lt;br&gt;7: $gf&lt;hr&gt;&lt;br&gt;"; } function __sleep() { echo "&lt;h3&gt;__sleep()&lt;/h3&gt;"; return($this); } function __wakeup() { echo "&lt;h3&gt;__wakeup()&lt;/h3&gt;"; }
  • 请记住,查询参数通常是有长度限制的。你不应该通过查询传递一个序列化的对象——你不知道它会有多大,其中一些可能会被默默地砍掉。同样,传递这样的会话数据会将其留在服务器的访问日志和其他地方的任何引用日志中。巨大的安全风险。但是如果你坚持这样做,那么尽可能地剥离代码。跳过 gzip/urleconding 并尝试仅传递纯序列化文本。
【解决方案2】:

看看3和6的数据,不一样!

发生的情况是 + 字符用作 URL 中的空格,因此“+”get 被解码为介于 5 和 6 之间的“”(我猜 5 是原始 $_GET 数据并表明它已经解码)

【讨论】:

    猜你喜欢
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多