# 輪読会2 ## 書籍 体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 https://amzn.to/38EvUMZ ## 開催日時 土曜 20:00 ~ 21:00 もくもく読書タイム 21:00 ~ 22:00 ディスカッションタイム ## 開催記録 ### 第1回 ~ 第17回 https://hackmd.io/CRME-k8-TIO7a5rtl1tWcw ### 第18回 8/21(土) 20:00 ~ 21:00 もくもくタイム 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.308(「4.12 ファイルアップロードにまつわる問題」)~ P.328(「4.12.4 PDFのFormCalcによるコンテンツハイジャック」の直前) #### 学習MEMO ##### 4.12 ファイルアップロードにまつわる問題 (P.308) 利用者がファイルをアップロードする機能や、利用者がアップロードしたファイルを別の利用者がダウンロードできる機能に発生しがちな脆弱性について説明。 ###### 4.12.1 ファイルアップロード問題の概要 アップローダに対する攻撃の種類 * アップロード機能に対するDoS攻撃 * アップロードされたファイルをサーバ上のスクリプトとして実行する攻撃 * 仕掛けを含むファイルを利用者にダウンロードさせる攻撃 * 閲覧権限のないファイルのダウンロード ◆ アップロード機能に対するDoS攻撃 攻撃内容 アップロード機能に対して大量のデータを送信し、Webサイトに過大な負荷を掛ける。 影響 応答速度の低下や、最悪の場合サーバの停止など 対策 アップロードファイルの容量制限が有効。 php.iniの設定で容量制限する方法。 upload_max_filesize, max_file_uploads, post_max_size, memory_limitの値をアプリケーションの要求を満たす最小値に設定する。 ファイルアップロード機能を提供しないアプリケーションの場合は、file_uploadsをOffにする。 Apacheのhttpd.confでリクエストボディサイズを絞る方法。 LimitRequestBodyの値を指定。 「COLUMN 使用メモリ量やCPU使用時間など他のリソースにも注意」 (P.309) Dos攻撃耐性を高める上では、他のパラメータもチェックするべき。 画像ファイルをサーバ上で変換する際はできるだけ早期に画像の幅・高さ・色数のチェックをするなど CPU負荷の高い処理については、CPUリソースを事前に見積もり、関連するパラメータを制限すると良い。 ◆ アップロードされたファイルをサーバ上のスクリプトとして実行する攻撃 攻撃内容 外部からアップロードされたスクリプトファイルがWebサーバ上で実行される 影響 情報漏えい、ファイル改ざん、他サーバへの攻撃など、OSコマンド・インジェクション攻撃と同じ影響があり得る ◆ 仕掛けを含むファイルを利用者にダウンロードさせる攻撃 (P.310) 攻撃内容 仕掛けを含ませたファイルを攻撃者がアップロードする 影響 攻撃者がアップロードしたファイルを利用者が閲覧すると、JavaScriptなどのクライアントスクリプトが実行されたり、マルウェア感染などが起こる 対策 マルウェア感染に対する直接の責任はアップロードした人にあるが、アップローダの運営側にも責任が及ぶ可能せいがある。 そのため、Webサイトのサービス仕様を検討する際に、マルウェア対策をサイト側で実施するかどうかをWebサイトの性質を元に検討する ◆ 閲覧権限のないファイルのダウンロード (P.311) 攻撃内容(問題) 限られた利用者のみがダウンロードできるはずのファイルが、権限のない利用者までもダウンロードできる 原因 ファイルに対するアクセス制限がかかっておらず、URLの推測によりファイルがダウンロードできてしまう ###### 4.12.2 アップロードファイルによるサーバー側スクリプト実行 ▶ 概要 利用者がアップロードしたファイルをWebサーバの公開ディレクトリに保存し、php、asp、aspx、jspなどのサーバ側で実行可能なスクリプト言語の拡張子を指定できる場合、スクリプトとしてサーバ上で実行できる。 この場合、OSコマンド・インジェクションと同様の影響がある。 ▶ 攻撃手法と影響 (P.312) アップロードファイルによるサーバー側スクリプト実行の攻撃パターンとその影響。 ◆ サンプルスクリプトの説明 4c-001.php ファイルアップロード画面。form要素のenctype属性が"multipart/form-data"になっていて、ファイルアップロードができる状態。 4c-002.php ファイルを受け取って、/4c/img/ディレクトリに保存した上で、画面にも表示する。 正常系の実行例 1. 画像ファイルをアップロードする 2. アップロードした画像ファイルが表示される 「COLUMN: ファイル名によるXSSに注意」 (P.314) Unixの場合、ファイル名として「<」、「>」、「*」などが使えるため、使う場所に応じたエスケープ処理が必要。XSSの対策を原則通り実施するべし。 ◆ PHPスクリプトのアップロードと実行 攻撃例 1. catコマンドで/etc/passwdの内容を表示するスクリプト4c-900.phpをアップロードする 2. 画像ではないので、アップロード完了画面ではx印が表示される 3. 4c-900.phpのリンクをクリックする 4. ブラウザ上に/etc/passwdの内容が表示される アップロードファイルによるサーバー側スクリプト実行の影響は、OSコマンド・インジェクションと同じ。 ▶ 脆弱性が生まれる原因 (P.315) 次の両方に該当すると脆弱性が生まれる * アップロードしたファイルが公開ディレクトリに保存される * アップロード後のファイル名として、「.php」「.asp」「.aspx」「.jsp」などサーバスクリプトを示す拡張子が指定できる ▶ 対策 拡張子の制限だけでは対策抜けが生じる可能性があるので、ファイルを公開ディレクトリに保存しない方法が望ましい。 この場合、アップロードされたファイルはスクリプト経由でダウンロードする。本書では目的のスクリプトを「ダウンロードスクリプト」と呼ぶ。 4c-002a.php 修正点 * ファイルの格納先をget_upload_file_name()が返すファイル名に変更 * 画像のURLをダウンロードスクリプト経由に変更 get_upload_file_name()でやっていること * 拡張子がgif, jpg, pngのいずれかであることを確認 * 元の拡張子を持ち、乱数を用いたユニークなファイル名に設定して保存 4c-003.php GETパラメータで渡されたファイル名の拡張子がgif, jpg, pngのいずれかであることを確認し、それぞれの拡張子に対応したContent-Typeを出力。その後ファイル本体を出力するダウンロードスクリプト。 この対策により、アップロードしたファイルをサーバスクリプトとして実行されることが防止できる。 「COLUMN: 拡張子をチェックする際の注意」 (P.318) SSI機能の設定やApacheの設定などによってスクリプトに割り当てられる拡張子が変わってくるため、拡張子のチェックには注意が必要。 拡張子によるチェックは必要最低限のもののみを許可し、特別な理由がなければダウンロードスクリプトを用いるべき。 ###### 4.12.3 ファイルダウンロードによるクロスサイト・スクリプティング (P.319) ▶ 概要 ファイルをダウンロードする際にブラウザがファイルのタイプを誤認することがあり、意図せずJavaScriptなどが実行されてしまう場合がある。 この脆弱性を悪用すると、ファイルダウンロードによるクロスサイト・スクリプティング(XSS)攻撃が成立する。 ▶ 攻撃手法と影響 (P.320) ◆ PDFダウンロード機能によるXSS PDFのようなアプリケーションファイルのダウンロードサービスを想定。 ◇ サンプルスクリプトの説明 4c-011.php ファイルをアップロードするフォームを表示。 action先のURLは4c-012.php 4c-012.php アップロードされたファイルを受け付ける。 ファイルの拡張子がpdf以外だった場合は、処理を中断する。 4c-013.php ダウンロードスクリプト。 Content-Typeにapplication/x-pdfを指定して、PDFファイルを出力する。 正常系 1. 4c-011.phpからPDFファイルをアップロード 2. 「アップロードしました」の文字列とダウンロードスクリプトへのリンクが表示される 3. リンクをクリックすると、PDFファイルをダウンロードするための画面が表示される ◇ PDFに偽造したHTMLファイルによるXSS (P.322) 攻撃例 1. script要素のみのHTMLファイルをpdf拡張子で保存し、4c-011.phpからアップロード 2. 「アップロードしました」の文字列とダウンロードスクリプトへのリンクが表示される 3. リンクのURLをコピーし、「4c-013.php」の後に「/a.html」という実際は存在しないHTMLファイルの名前を挿入する 4. 加工したURLにアクセスすると、IEではJavaScriptが実行される FireFoxやChromeでは、アップロードした内容が記述されたa.htmlがダウンロードされる。ダウンロードしたa.htmlをローカルで実行してもXSSには至らないので、このリンクを利用者に踏ませてXSSを発生させられるのはIE限定。 ◇ Content-Typeの間違いが根本原因 (P.324) PDFの正しいContent-Typeは「application/pdf」。 「application/x-pdf」は誤り。 ▶ 脆弱性が生まれる原因 ブラウザが対応していないCotent-Typeが指定されていると、ブラウザがコンテンツをHTMLと解釈してしまいJavaScriptが実行されてしまう可能性があり、XSSが発生し得る。 Content-Typeが間違っていた場合も同様。 ◆ Content-TypeとIEの挙動の関係 IEが扱えるContent-Typeの場合はContent-Typeに従うが、そうでない場合はURLに含まれる拡張子からファイルタイプを判定する仕様。 扱えるContent-Typeの種類はレジストリに登録されている。 ▶ 対策 (P.325) ファイルのアップロード時とダウンロード時にそれぞれ対策を行う。 ◆ ファイルアップロード時の対策 * 拡張子が許可されたものかチェックする 4.12.2のときと同様に、ファイルの拡張子を取り出して許可されたものであるかどうかを確認する ◆ ファイルダウンロード時の対策 (P.326) * Content-Typeを正しく設定する(必須) * レスポンスヘッダX-Content-Type-Options: nosniffを指定する(必須) * 必要に応じてContent-Dispositionヘッダを設定する * PDFを扱う場合は、4.12.4項の対策をあわせて実施する ◇ Content-Typeを正しく設定する Cotent-Typeを正しく設定することはIEに限らずすべてのブラウザに必要な処理である。 ダウンロードスクリプト経由でなく、ファイルを公開ディレクトリ内に置く場合はWebサーバの設定を確認する。 ◇ レスポンスヘッダX-Content-Type-Options: nosniffを指定する X-Content-Type-Options: nosniffを指定することによって、ブラウザがContent-Typeヘッダのみからファイルタイプを解釈するようになる。 明示的にtext/htmlを指定しない限りはJavaScriptは実行されなくなる。 ApacheやnginxなどのWebサーバ側で設定しておくと良い。 ◇ 必要に応じてContent-Dispositionヘッダを設定する (P.327) Content-Disposition: attachmentを指定することで、ファイルをWebページとして表示せず「ダウンロードすべきファイル」という扱いになる。 この場合、Content-Typeもapplication/octet-streamに指定すると、ファイルタイプ上でもダウンロードすべきファイルになる。 ◇ その他の対策 利用者のブラウザで本当に表示できるかどうかまでは確認できないため、Webアプリケーションの仕様策定時に次のようなチェックを行うかどうかを検討する。 * ファイルサイズ以外の縦横サイズ、色数などのチェック * 画像として読み込めるかどうかのチェック * ウィルス・スキャン * コンテンツの内容チェック(自動あるいは手動) * アダルトコンテンツ * 著作権を侵害するコンテンツ * 法令、公序良俗に反するコンテンツ * その他 ▶ まとめ ファイルのアップロードとダウンロード問題の基本は、Content-Typeと拡張子を正しく設定すること。 あわせてX-Content-Type-Options: nosniffの指定を推奨する。 ### 第19回 9/11(土) ※ もくもくタイムはお休み 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.328(「4.12.4 PDFのFormCalcによるコンテンツハイジャック」)~ P.342(「4.14 構造化データの読み込みにまつわる問題」の直前) #### 学習MEMO ###### 4.12.4 PDFのFormCalcによるコンテンツハイジャック (P.328) ▶ 概要 PDF1.5以降では、PDFドキュメントにFormCalcスクリプトを埋め込むことができる。 Adobe Acrobat Readerに実装されたFormCalcには、HTTPリクエストを呼び出して結果を受け取ることのできるURL関数がある。 このFormCalcのURL関数を悪用した攻撃手法が考案されている。 主にIEが対象ブラウザとなる。 ▶ 攻撃手法と影響 1. 攻撃者がFormCalcスクリプトを埋め込んだPDFファイルを攻撃対象サイトexample.comにアップロードする 2. 攻撃者が、example.comにアップロードしたPDFファイルを罠サイトの罠ページに埋め込む 3. 罠ページにexample.jpのユーザを誘導する 4. 誘導されたユーザ(被害者)が、example.jpにログインした状態で罠ページを閲覧する 5. 罠ページに埋め込まれたPDFのFormCalcスクリプトからexample.jpにHTTPリクエストが送られる 6. ブラウザが保持しているexample.jpのクッキーがリクエストに付与される 7. example.jpが被害者の秘密情報を返す 8. 罠ページのJavaScriptとFormCalcが連携して、秘密情報を攻撃者が受け取る インターネットオプションの「信頼済みサイト」あるいは「ローカルイントラネット」に攻撃対象サイトが登録されている場合は、Adobe Acrobat ReaderからのHTTPリクエストにクッキーは付与されない。 ▶ 脆弱性が生まれる原因 (P.332) Adobe Acrobat Readerの仕様が原因。 ▶ 対策 * PDFファイルはブラウザ内で開かずダウンロードを強制する * PDFをobject要素やembed要素では開けない仕組みを実装する ◆ PDFファイルはブラウザ内で開かずダウンロードを強制する PDFファイルをブラウザ内で開くと、Webサイト側でFormCalスクリプトの実行を防ぐことができない。 ダウンロード時のヘッダーを Content-Type: application/octet-stream Content-Disposition: attachement; filename="hogehoge.pdf" X-Download-Options: noopen のように設定し、ブラウザで開かれないようにする。 ◆ PDFをobject要素やembed要素では開けない仕組みを実装する (P.333) object要素やembed要素でPDFファイルを開こうとすると、レスポンスヘッダは無視されてしまうため、object要素やembed要素では開けない仕組みを実装する。 もっとも単純な方法は、ファイルダウンロードをPOSTリクエストに限定すること。 ▶ まとめ (P.334) PDFのFormCalcによるコンテンツハイジャックは、PDFのセキュリティ上好ましくない仕様を悪用した攻撃。 利用者にアップロードを許可する場合は、本当に必要かどうかを吟味した上で、リスク分析と慎重な対策を行うべし。 ##### 4.13 インクルードにまつわる問題 ###### 4.13.1 ファイルインクルード攻撃 (P.335) ▶ 概要 スクリプト言語でソースの一部を外部から指定した別ファイルから読み込むとき、不正なファイルを指定できることを「ファイルインクルード脆弱性」と呼ぶ。 PHPの場合は設定によっては外部サーバのURLをファイル名として指定できる場合もある。これを「リモート・ファイルインクルート(RFI)」と呼ぶ。 ▶ 攻撃手法と影響 (P.336) サンプルスクリプト 4d-001.php body要素内で、外部から渡されたGETパラメータの値に'.php'を加えたファイルを読み込む。 spring.php 文字列とbr要素が書かれている。 正常系の処理 1. headerパラメータに'spring'という値を渡して4d-001.phpにアクセス 2. spring.phpに書かれた文字列とbr要素がブラウザで表示される ◆ ファイルインクルードによる情報漏洩 (P.337) 攻撃例 1. headerパラメータに'../../../../../etc/hosts%00'を渡して4d-001.phpにアクセス 2. ブラウザに/etc/hostsの内容が表示される → ディレクトリ・トラバーサル脆弱性と同様に、Webサーバ内の非公開ファイルの漏洩が起こる (%00: NULL文字) ◆ スクリプトの実行1:リモート・ファイルインクルード攻撃(RFI) PHPには、外部サーバのファイルをインクルードできる機能がある。 非常に危険なため、PHP5.2.0以降ではデフォルトで無効になっている。 脆弱性がある状態で設定を有効にすると、次のような攻撃が通る。 1. 外部サーバにphpinfo()を実行するコードが書かれたtxtファイルを用意する 2. headerパラメータに1のファイルのURLと、末尾に?を渡して4d-001.phpにアクセス 3. 末尾に?があることで、'.php'はクエリ文字と認識される 4. ブラウザにphpinfo()の結果が表示される phpinfo()のHostヘッダから、example.jp上でPHPが実行されたことがわかる。 「COLUMN:RFIの攻撃のバリエーション」 (P.339) RFIが有効になっている場合、data:ストリームラッパーやPHP入力ストリームを使ってより簡単に攻撃することも可能。 allow_url_includeをOffにすることで対策できる。 ◆ スクリプトの実行2:セッション保存ファイルの悪用 RFIが禁止されていても、次のいずれかのようなサイトでファイル名を推測できる場合にはファイルインクルード攻撃でスクリプトを実行される可能性がある。 * ファイルのアップロードが可能 * セッション変数の保存先がファイル 例)セッション変数の保存先がファイルのケース 1. フォームから送られた値をそのままセッション変数に格納 2. セッション変数の格納先を出力(出力しなくても、デフォルトのパスやクッキーの値から推測が可能なことが多い) 3. headerパラメータにセッションファイル名と%00を渡して4d-001.phpにアクセス 4. ブラウザにphpinfo()の結果が表示される ▶ 脆弱性が生まれる原因 (P.342) ファイルインクルード脆弱性が発生する条件 * インクルードファイル名を外部から指定することができる * インクルードすべきファイル名かどうかの妥当性チェックをしていない ▶ 対策 ディレクトリ・トラバーサル脆弱性の場合と同様に考える。 * 外部からファイル名を指定する仕様を避ける * ファイル名を英数字に限定する 保険的対策 RFI設定を禁止する。 allow_url_includeがOffになっていればOK。 ▶ まとめ 影響の大きな脆弱性なので、十分な対策をしましょう。 ### 第20回 10/16(土) ※ もくもくタイムはお休み 21:00 ~ 22:00 ディスカッションタイム #### 予定 P.343 (「4.14 構造化データの読み込みにまつわる問題」)~ P.360(「4.14.3 XML外部実体参照(XXE)」 の直前) #### 学習MEMO ##### 4.14 構造化データの読み込みにまつわる問題 (P.343) XMLやJSONなどの構造を持ったデータを保存や伝送に適したバイト列に変換することをシリアライズといいます。 この節では、シリアライズやその周辺の技術にまつわる処理に起因する次の3つの脆弱性について説明します。 * evalインジェクション * 安全でないデシリアライゼーション * XXE ###### 4.14.1 evalインジェクション ▶ 概要 構造を持ったデータの例として、プログラムのソースコードを用いるケースがある。 各言語にソースコードを解釈実行するevalと呼ばれる機能や関数があり、各言語のソースコードをデータとして扱うことが可能。 このevalの利用法に問題がある場合、外部から送り込んだスクリプトが実行される場合がある。 このような攻撃をevalインジェクション攻撃といい、そのような攻撃を受ける脆弱性をevalインジェクション脆弱性と呼ぶ。 ▶ 攻撃手法と影響 (P.344) ◆ 脆弱なアプリケーションの説明 複雑なデータを文字列に変換(シリアライズ)してフォーム間を受け渡しする場合の脆弱性を説明。 4e-001.php PHPのvar_export関数を使って配列をシリアライズした上で、Base64エンコードしたものを4e-002.phpへGETリクエストで送る 4e-002.php 受け取ったデータをBase64デコードし、eval関数を用いて元のデータに戻した結果をvar_dump関数で表示 正常系の処理 1. 配列をシリアライズ化し、エンコードした値をdataパラメータとして4e-002.phpにGETリクエストを送る 2. 配列の値がvar_dump()により表示される ◆ 攻撃手法の説明 (P.346) 4e-002.phpでeval関数に渡す引数はチェックされていないので、式の後に任意の文を追加できる脆弱性があるため、次のような手順で任意の処理を実行させることができてしまう。 1. 「0; phpinfo();」をBase64エンコードした値をdataパラメータとして4e-002.phpにGETリクエストを送る 2. phpinfo()の結果が表示される ▶ 脆弱性が生まれる原因 (P.347) * evalを用いること自体が危険 * evalに与えるパラメータのチェックがされていない PHPには、create_function()など、eval()の他にもに入力文字列を解釈して実行する関数がある。 また、引数として関数名を指定できる関数も、外部から指定できる場合は脆弱性になり得る。 ▶ 対策 (P.348) 優先度が高い順に、次の対策方法がある。 * eval(同等機能含む)を使わない * evalの引数に外部からのパラメータを指定しない * evalに与える外部からのパラメータを英数字に制限する ◆ evalを使わない まずはevalを使わないことを検討する。 もしevalを使いたい理由がシリアライズ目的であれば、次のような他の選択肢を使用する。 * implode / explode * json_encode / json_decode * serialize / unserialize implode / explode … 単純な配列のシリアライズが可能 json_encode / json_decode … 自由度と安全性のバランスが良く、多くの場合におすすめ serialize / unserialize … オブジェクトのシリアライズも可能だが、安全でないデシリアライゼーションの原因にもなり得る ◆ evalの引数に外部からのパラメータを指定しない 4e-002.phpの例では、hiddenパラメータではなくセッション変数で受け渡しすれば安全だった。 ただし、ファイルやDB経由でスクリプトを注入できる可能性のある場合はこの対策は使えない。 ◆ evalに与える外部からのパラメータを英数字に制限する 記号文字が使えなければ、スクリプトの注入はできない。 ◆ 参考:Perlのevalブロック形式 Perl言語のevalには2種類の形式がある。 * evalの後に式が続く形式 * evalの後にブロックが続く形式 後者はevalインジェクションの余地はなく、安全に使用できる。 ▶ まとめ (P.350) evalは強力な機能であるがゆえに影響も甚大なため、極力使わない実装をおすすめする。 ▶ さらに進んだ学習のために preg_replaceのe修飾子による脆弱性の可能性について詳しく知りたい場合は、寺田健氏のブログ記事を読むと良い。 ###### 4.14.2 安全でないデシリアライゼーション ▶ 概要 信頼できないシリアライズ済みデータをデシリアライズする場合、意図しないオブジェクトがアプリケーション内に生成され、場合によっては任意のコードを実行されてしまう可能性がある。 安全でないデシリアライゼーションは、OSコマンド・インジェクション攻撃と同様の影響がある。 ▶ 攻撃手法と影響 (P.352) ◆ 脆弱なアプリケーションの説明 クッキーに「好きな色」を複数保存するWebアプリケーションが題材。 英単語文字列の配列をシリアライズ化して保持する。 PHPでシリアライズ化すると、データの先頭に型とサイズがあり、その後のデータ実体を示す文字列が続く形式となる。 脆弱なアプリケーション例 4e-010.php 色の英単語を格納した配列をシリアライズ化し、クッキーに保存するスクリプト。 4e-011.php クッキーからシリアライズ化された色配列を取り出しデシリアライズし、foreach()で配列の値を一つずつhtmlspecialchars()でエスケープしながら出力。 これを実行すると、「好きな色は red green blue です」と出力される。 一見悪用できなさそうに見えるが、4e-011.phpの冒頭でログ管理のためのLoggerクラスファイルを呼び出している。 Loggerクラスでは、ログをメモリ上にバッファし、アプリケーション終了時にログをファイル出力することができる。 ◆ 攻撃手法の説明 (P.354) 1. 攻撃用のスクリプト4e-900.phpを用意する 4e-900.php 特定のファイルにphpinfo()を実行させる処理を保存するLoggerクラスを定義。 Loggerクラスのインスタンスをシリアライズ化して、COLORSクッキーに保存する。 また、攻撃用にこの値を出力する。 2. 4e-900.phpを実行し、攻撃用のクッキーの値をコピーする 3. OWASP ZAPの機能を使用し、Cookieの値を攻撃用の値に書き換えた状態で4e-011.phpの実行を進める 5. 画面上には「好きな色は です」と表示される 6. 攻撃対象さいとのxinfo.phpにアクセスすると、phpinfo()の実行結果が表示される 外部から注入したPHPスクリプトが実行されてしまった。 ▶ 脆弱性が生まれる原因 (P.357) 脆弱なスクリプトが攻撃用クッキー(Loggerクラスのインスタンスをシリアライズ化したもの)を読み込みデシリアライズすると、メモリ上に filename : ../var/www/html/xinfo.php log : <?php phpinfo(); ?> というオブジェクトが生成される。 このオブジェクトが破棄されるタイミングで、4e-012.phpで定義されていた同名のクラスのデストラクタが実行されxinfo.phpにphpinfo()を実行する処理が書き込まれた。 ◆ 安全でないシリアライゼーションにより悪用できるメソッド (P.358) 悪用されやすいメソッド * デストラクタ … オブジェクトが破棄されるタイミングで実行される * unserialize_callback_func … 未定義のクラスをシリアライズした場合に実行される * \_\_wakeup() … デシリアライズしたクラスに定義されていた場合に実行される * \_\_toString() … デシリアライズしたクラスに定義されていて、オブジェクトを文字列に変換しようとした場合に実行される https://www.php.net/manual/ja/language.oop5.magic.php#object.wakeup ◆ 攻撃に悪用できるクラスの条件 PHPの場合、デシリアライズできるクラスは、攻撃対象アプリケーション内であらかじめ定義されているか、api_autoload_register関数などにより自動的にクラス定義が読み込まれるものに限る。 一方Javaの場合は、クラスパスの通っているパスに含まれるクラスはすべて対象となる。 ▶ 対策 (P.359) * シリアライズ形式ではなくJSON形式によりデータを受け渡す * クッキーやhiddenパラメータではなくセッション変数など書き換えできない形でシリアライズ形式のデータを受け渡す * HMACなどの改ざん検知の仕組みを導入データが改ざんされていないことを確認する 安全でないデータをシリアライズすることは、なるべく避ける。 対策例 4e-010a.php 配列をシリアライズの代わりにJSONエンコードしてクッキーに保存 4e-011a.php デシリアライズの代わりにJSONデコードして配列の値を取り出す。 実行結果は変わらないまま、安全でないデシリアライゼーションの問題は発生しなくなった。 ### 第21回 10/30(土) 21:00 ~ 22:00 #### 予定 P.360 (「4.14.3 XML外部実体参照(XXE)」)~ 376 or 386 #### 学習MEMO ###### 4.14.3 XML外部実体参照(XXE) (P.360) ▶ 概要 XMLデータを外部から受け取るプログラムは、外部実体参照の形でWebサーバー内部のファイルなどを不正に読み取られる可能性がある。この攻撃をXML外部実体参照(XXE)攻撃と呼び、XXE攻撃ができてしまう脆弱性をXXE脆弱性と呼ぶ。 ▶ 攻撃手法と影響 (P.361) ◆ 外部実体参照とは XMLではENTITY宣言を行い、実体参照(&xxx;の形)で呼び出すことができる。 <!DOCTYPE foo [ <!ENTITY greeting "こんにちは"> <!ENTITY external-file SYSTEM "external.txt"> ]> external.txtの中身が「Hello World」だった場合、&external-file;と書いた部分は「Hello World」と展開される。 ◆ サンプルスクリプトの説明 (P.362) 4e-020.html XMLをアップロードするフォーム 4e-021.php アップロードされたXMLファイルを解析し出力する 正常系の処理 1. name要素に安全太郎、address要素に東京都港区の文字列が書かれたXMLファイルをアップロード 2. 氏名:安全太郎、住所:東京都港区と表示される ◆ 外部実体参照によるアクセス (P.363) 攻撃例 1. name要素に安全太郎、address要素に「/etc/hosts」というファイル名を定義した実態参照が書かれたXMLファイルをアップロード 3. 住所欄に/etc/hostsファイルの中身が表示される ◆ URL指定のHTTPアクセスによる攻撃 (P.364) 攻撃例 1. name要素に安全太郎、address要素にURLが指定された実体参照が書かれたXMLファイルをアップロード 2. 住所欄に指定されたURLへのアクセス結果が外部実体参照により展開された内容が表示される ※ ただし、展開結果のXMLが整形式でない場合には参照に失敗する。 ◆ PHPフィルタによる攻撃 (P.365) xxe-03.xmlのようにPHPフィルタを利用すると、外部実体参照の展開結果がXMLの整形式でない場合にも参照が成功する。 ◆ Java言語での脆弱なサンプル 4e-022.html XMLデータをtextarea要素から登録するHTMLフォーム。 C4e_023.java XMLデータを受け取り、XML形式を解析して個人情報登録するサーブレット。 正常系の処理 (P.367) 1. xxe-00.xmlと同様のXMLデータをtextareaに入力して送信 2. XMLデータが読み取られ、表示される。 攻撃例 1. xxe-01.xmlと同様のXMLデータをtextareaに入力して送信 2. /etc/hostsのデータが出力される。 また、ローカルファイル名の代わりにURLを指定することにより、Webサーバを踏み台として他のサーバにアクセスすることも可能。 ▶ 脆弱性が生まれる原因 (P.368) XMLの外部実体参照を使って、XML中に外部のファイルを流し込むことができるのはXMLに元から存在する機能。 XXEは、この機能を悪用したものである。 ▶ 対策 外部実体参照を禁止する指定を行うことが基本となる。 ◆ PHPにおけるXXE対策 * XMLの代わりにJSONを用いる * libxml2のバージョン2.9以降を用いる * libxml_disable_entity_loader(true)を呼び出す ◆ XMLの代わりにJSONを用いる JSONでは安全でないデシリアライゼーションやXXEなどの問題は通常発生しないので、外部とのデータ交換にはJSONを使う方が安全。 ただし、SOAPのようにプロトコルでXMLを採用している場合は次のような方法で対策する。 ◆ libxml2のバージョン2.9以降を用いる (P.369) libxml2のバージョン2.9以降では、デフォルトで外部実体参照を停止する設定になっているのでXXEに対して脆弱ではない。 ただし、PHP側で許可する設定に書き換えている場合は例外。 ◆ libxml_disable_entity_loader(true)を呼び出す libxml_disable_entity_loader(true)を呼び出すことで、libxml2やPHPの設定に関わらず、外部実体参照を禁止することができる。 ◆ Java言語におけるXXE対策 デフォルトで外部実体参照が有効になっている場合が多いので、アプリケーション側で対策する必要がある。 マニュアルなどでDTDあるいは外部実体参照を禁止する方法を確認しよう。 ▶ まとめ (P.370) PHPを使う限りは、libxml2のバージョンアップあるいはパッチ適用により対策されるが、Java言語の場合はアプリケーション側での対策が必要になるため、より注意が必要。 ##### 4.15 共有資源やキャッシュに関する問題 (P.371) この節では、競合状態の脆弱性とキャッシュからの情報漏洩について説明します。 ##### 4.15.1 競合状態の脆弱性 ▶ 概要 共有資源とは、複数のプロセスやスレッドから同時に利用している変数、共有メモリ、ファイル、データベースなどのことを指す。 共有資源に対する排他制御が不十分だと競合状態の脆弱性の原因となる場合がある。 影響の代表例 * 別人の個人情報などが画面に表示される(別人問題) * データベースの不整合 * ファイル内容の破壊 ▶ 攻撃手法と影響 (P.372) C4f-001.java クエリー文字列nameを受け取ってインスタンス変数nameに代入し、3秒間待ってからインスタンス変数nameを表示するサーブレット。 1. ブラウザのウィンドウを2枚開いておく 2. 片方のウィンドウで、name=yamadaとして起動する 3. 1秒後に、別のウィンドウでname=tanakaとして起動する 4. 両方のウィンドウでname=tanakaと表示される 別人問題と呼ばれる現象で、一種の個人情報漏洩にあたる。 デフォルト設定では各サーブレットクラスのインスタンスは1つだけ生成されてすべてのリクエストを処理する。そのため、サーブレットクラスのインスタンス変数はすべてのリクエストが共有する共有資源となる。 ▶ 脆弱性が生まれる原因 (P.374)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up