現在の位置: ホーム> 最新記事一覧> セキュリティをシリアル化して安全ではありません:オブジェクトインジェクション攻撃を防ぐ方法は?

セキュリティをシリアル化して安全ではありません:オブジェクトインジェクション攻撃を防ぐ方法は?

gitbox 2025-05-19

広く使用されているサーバー側のプログラミング言語として、PHPはWeb開発において重要な位置を占めています。ますます多くのPHPアプリケーションがインターネットにさらされるにつれて、セキュリティの問題は徐々に開発者の焦点になりつつあります。 PHPでは、 Serialize()およびunserialize()関数は、オブジェクトと配列のシリアル化と脱滑りを処理するために広く使用されています。ただし、これらの機能は、攻撃者が「オブジェクトインジェクション攻撃」を行う潜在的な脆弱性になる可能性があります。防止されない場合、攻撃者は慎重に構築された悪意のあるデータを介してアプリケーションの動作を変更し、リモートコード実行(RCE)などの深刻なセキュリティ問題にさえつながる可能性があります。

この記事では、PHPのSerialize()およびUnserialize()関数のセキュリティ問題を分析し、オブジェクト注入攻撃を防ぐための効果的な手段を提供します。

PHPのシリアル化および非正規化関数の概要

serialize()およびunserialize()は、オブジェクトと配列のシリアル化と降下のためのPHPの2つの重要な機能です。

  • Serialize() :PHP変数(オブジェクト、配列などを含む)を保存または転送できる文字列に変換します。たとえば、オブジェクトまたは配列を文字列に変換してデータベースに保存できます。

  • Unserialize() :シリアル化された文字列をPHPの元のデータ型(オブジェクトや配列など)に再構成することです。

 $data = ['name' => 'John', 'age' => 30];
$serializedData = serialize($data);
echo $serializedData;  // 出力:a:2:{s:4:"name";s:4:"John";s:3:"age";i:30;}

上記のコードは、配列$データを文字列にシリアル化します。データベースに保存すると、後でunserialize()を介して元の配列に復元できます。

オブジェクト注入攻撃の原理

オブジェクトインジェクション攻撃とは、攻撃者が特別なシリアル化データを構築することを指し、PHP Unserialize()関数が悪意のあるコードを実行するか、データを脱却するときにアプリケーションの動作を変更します。このタイプの攻撃は通常、PHPアプリケーションが入力データを完全に検証しない場合に発生します。

たとえば、攻撃者が次の悪意のあるデータを構築するとします。

 $maliciousData = 'O:8:"UserClass":1:{s:4:"name";s:4:"evil";}';
unserialize($maliciousData);

その中で、 UserClassはアプリケーションのクラスです。攻撃者は、シリアル化されたデータを介して悪意のあるオブジェクトを作成し、検証なしでunserialize()関数に渡し、それによりオブジェクトのコンストラクターをトリガーし、セキュリティの脆弱性につながる可能性があります。

オブジェクトインジェクション攻撃を防ぐ方法は?

オブジェクト注入攻撃を防ぐために、開発者は次の効果的な測定値をとることができます。

1.信頼できないクラスの自動負荷を無効にします

脱必要なプロセス中、データにクラス名が含まれている場合、 Unserialize()関数はクラスをロードしようとします。適切なセキュリティ対策なしにクラスがアプリケーションに存在する場合、悪意のあるオブジェクトを作成および実行することができます。したがって、脱介入中にロードされることが許可されているクラスは、 unserialize()approad_classesパラメーターによって制限される可能性があります。

 $data = 'O:8:"UserClass":1:{s:4:"name";s:4:"evil";}';
$unserializedData = unserialize($data, ['allowed_classes' => ['UserClass']]);

クラス名が明示的にリストされていない場合、PHPは不明なクラス名を含むデータの降伏を許可しません。

2。入力データをフィルタリングして確認します

入ってくるシリアル化されたデータを厳密に検証およびフィルタリングして、悪いコンテンツが含まれていないことを確認します。データを受け入れる前に、正規表現またはその他の方法を使用して、シリアル化された文字列の構造が合法かどうかを確認できます。

 if (preg_match('/^[O|a|s|i|d|b|f|N|r|C|l|n]/', $inputData)) {
    $unserializedData = unserialize($inputData);
} else {
    die('Invalid serialized data');
}

3.シリアル化の代わりにJSONを使用します

特別な要件がない場合は、 serialize()unserialize()の代わりにjson_encode()json_decode()を使用することをお勧めします。 JSON_ENCODE()およびJSON_DECODE()は、シンプルなデータ型(配列、オブジェクト、文字列、数字など)のみを扱うことができ、複雑なクラスやオブジェクトを含むことができないため、オブジェクトインジェクション攻撃に簡単に悪用されません。

 $data = json_encode($dataArray);
$decodedData = json_decode($data, true);

4. PHPの構成ファイルを使用して、危険な機能を無効にします

PHP.ini構成ファイルでは、特定の機能を無効にして、これらの機能の開発者の偶発的な使用を避けることにより、セキュリティを強化できます。攻撃者がUnserialize()を介してセキュリティの脆弱性を引き起こすのを防ぐために、 Unserialize()関数を無効にするか、それを信頼できる範囲に制限することができます。

 disable_functions = "unserialize"

5。PHPおよびセキュリティパッチの最新バージョンを使用します

PHPコミュニティは、潜在的なセキュリティの脆弱性を修正するために、更新とセキュリティパッチを定期的にリリースします。開発者は常にPHPの最新バージョンを使用し、セキュリティを確保するためにタイムリーにシステムを更新する必要があります。

実用的な保護:機密データを処理する際のセキュリティベストプラクティス

Serialize()およびUnserialize()関数を直接保護することに加えて、開発者は機密データの全体的なセキュリティ管理を強化する必要もあります。セキュリティベストプラクティスは次のとおりです。

  1. 暗号化された機密データ:AS暗号化などの強力な暗号化アルゴリズムを使用して暗号化された機密データが保存または送信された場合、攻撃者がデータを取得しても、簡単にクラックできないことを確認します。

  2. 入力検証:すべてのユーザー入力、特にURL、フォーム、またはAPIを介して受信したデータを厳密に検証します。既存のライブラリを使用して、SQL注入、XSS、CSRFなどの一般的な攻撃を防ぐことができます。

  3. オブジェクトの露出を最小限に抑える:敏感なオブジェクトや複雑なオブジェクトがクライアントに直接露出しないようにしてください。シリアル化する必要があるデータには、必要な情報のみが含まれている必要があります。

要約します

PHPのSerialize()およびUnserialize()関数は、開発者に便利なデータストレージと伝送メカニズムを提供しますが、制限なしでそれらを使用すると、深刻なセキュリティリスクが発生します。合理的な構成、入力検証、代替の使用、PHPバージョンのタイムリーな更新により、オブジェクトインジェクション攻撃を効果的に防ぐことができます。

最も重要なことは、ユーザー入力を決して信用しないでください!合理的なセキュリティ戦略と保護対策は、アプリケーションのセキュリティを効果的に改善し、潜在的なリスクを減らすことができます。