この記事では、PHP デシリアライゼーションの脆弱性シリーズで、PHP のシリアル化とデシリアライゼーションの原則に関する関連知識を共有します。これが必要な友人は参照してください。
0. はじめに
オブジェクトのシリアル化および逆シリアル化関数については、詳細には説明しません。PHP でのシリアル化の結果は、PHP でカスタマイズされた文字列形式になります。 json に似ています。
任意の言語でオブジェクトのシリアル化と逆シリアル化を設計するときは、いくつかの問題を解決する必要があります。
オブジェクトをシリアル化した後、シリアル化の結果は自己記述関数 (シリアル化の結果からこのオブジェクトの特定の型を取得します。
#型を知るだけでは十分ではありません。もちろん、この型に対応する特定の値も知る必要があります)。
シリアル化中の権限制御、シリアル化フィールドなどをカスタマイズできます。たとえば、golang で行うと非常に便利です。
時間パフォーマンスの問題: 一部のパフォーマンス重視のシナリオでは、オブジェクトのシリアル化例: 高パフォーマンスのサービス (シリアル化に protobuf をよく使用します)
スペースのパフォーマンスの問題: シリアル化後の結果が長すぎてはなりません (メモリ内の int など) オブジェクト, シリアル化後、データ長が int の長さの 10 倍になる場合、このシリアル化アルゴリズムには問題があります。
この記事では、PHP コードの観点から PHP のシリアル化と逆シリアル化についてのみ説明します。
#1. シリアル化と逆シリアル化のメソッド unserialize
class fobnn { public $hack_id; private $hack_name; public function __construct($name,$id) { $this->hack_name = $name; $this->hack_id = $id; } public function print() { echo $this->hack_name.PHP_EOL; } } $obj = new fobnn('fobnn',1); $obj->print(); $serializedstr = serialize($obj); //通过serialize接口序列化 echo $serializedstr.PHP_EOL;; $toobj = unserialize($serializedstr);//通过unserialize反序列化 $toobj->print();
fobnn O:5:"fobnn":2:{s:7:"hack_id";i:1;s:16:"fobnnhack_name";s:5:"fobnn";} fobnn
#2. パフォーマンスの問題
PHP シリアル化の時間パフォーマンスはこの記事では分析されません。詳細は後述しますが、シリアル化の結果は実際には次のとおりです。 json/bson で定義 プロトコルにはプロトコルヘッダーがあり、プロトコルヘッダーには型が記述され、プロトコルボディには型に応じた値が記述されます。シリアル化結果は圧縮されません。逆シリアル化メソッドのマジック
は、上で説明した 2 番目の問題に対応します。実際、PHP にも解決策があります。1 つはマジック メソッド、もう 1 つはカスタム シリアル化関数によるものです。マジック メソッド __sleep と __wakeup
class fobnn { public $hack_id; private $hack_name; public function __construct($name,$id) { $this->hack_name = $name; $this->hack_id = $id; } public function print() { echo $this->hack_name.PHP_EOL; } public function __sleep() { return array("hack_name"); } public function __wakeup() { $this->hack_name = 'haha'; } } $obj = new fobnn('fobnn',1); $obj->print(); $serializedstr = serialize($obj); echo $serializedstr.PHP_EOL;; $toobj = unserialize($serializedstr); $toobj->print();
fobnn O:5:"fobnn":1:{s:16:"fobnnhack_name";s:5:"fobnn";} haha
interface Serializable { abstract public string serialize ( void ) abstract public void unserialize ( string $serialized ) }
#このインターフェイスを通じて、シリアル化と逆シリアル化の動作をカスタマイズできます。この関数は主にシリアル化形式をカスタマイズするために使用できます。
class fobnn implements Serializable { public $hack_id; private $hack_name; public function __construct($name,$id) { $this->hack_name = $name; $this->hack_id = $id; } public function print() { echo $this->hack_name.PHP_EOL; } public function __sleep() { return array('hack_name'); } public function __wakeup() { $this->hack_name = 'haha'; } public function serialize() { return json_encode(array('id' => $this->hack_id ,'name'=>$this->hack_name )); } public function unserialize($var) { $array = json_decode($var,true); $this->hack_name = $array['name']; $this->hack_id = $array['id']; } } $obj = new fobnn('fobnn',1); $obj->print(); $serializedstr = serialize($obj); echo $serializedstr.PHP_EOL;; $toobj = unserialize($serializedstr); $toobj->print();
fobnn C:5:"fobnn":23:{{"id":1,"name":"fobnn"}} fobnn
4.PHP 動的型と PHP 逆シリアル化
上記の自己記述関数では、オブジェクトの型がシリアル化結果に保存され、PHP は動的型言語であるため、
class fobnn
{
public $hack_id;
public $hack_name;
public function __construct($name,$id)
{
$this->hack_name = $name;
$this->hack_id = $id;
}
public function print()
{
var_dump($this->hack_name);
}
}
$obj = new fobnn('fobnn',1);
$obj->print();
$serializedstr = serialize($obj);
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);
$toobj->print();
$toobj2 = unserialize("O:5:\"fobnn\":2:{s:7:\"hack_id\";i:1;s:9:\"hack_name\";i:12345;}");
$toobj2->print();
string(5) "fobnn" O:5:"fobnn":2:{s:7:"hack_id";i:1;s:9:"hack_name";s:5:"fobnn";} string(5) "fobnn" int(12345)
##オブジェクトが正常にシリアル化されて戻されたことがわかります! そして、正常に動作することができます! もちろん、PHP のこのメカニズムは柔軟で変更可能な構文を提供しますが、セキュリティ リスクももたらします。 PHP のシリアル化および逆シリアル化機能によって引き起こされるセキュリティ問題を分析するために使用します。
上記は、PHP のシリアル化および逆シリアル化の原則についてまとめたすべての知識です。PHP 中国語 Web サイトのサポートについてご理解いただき、ありがとうございます。
興味があるかもしれない記事:
Swoole に基づく WeChat コード スキャン ログイン機能のコード実装プロセスの説明
PHPの関数メソッドによるlibライブラリの利用方法の詳細説明拡張機能の開発
以上がPHP のシリアル化と逆シリアル化の原理の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。