PHPカンファレンス2017 レポート

徳丸浩さん,著名PHPアプリの脆弱性に学ぶセキュアコーディングの原則 〜PHPカンファレンス2017 ゲストスピーカーセッション

この記事を読むのに必要な時間:およそ 2.5 分

局所的に絶対安全な方法で実装すれば,脆弱性は混入しない

開発の現場では「信頼されたデータ」が要求される際に「信頼境界の外へ,本当に値が出ていないか⁠⁠,この確認が漏れてしまうことが多くあると注意を促しました。たとえば,hiddenパラメーターでSQL文を渡しているコードなどです。徳丸さん自身も,納品する直前のもので目にした経験があったそうです。徳丸さんは,⁠局所的に安全を積み重ねることが,脆弱性を作り込まない早道」であると考えをまとめました。

画像

講演の後半は,ケーススタディーとして,いくつかのPHPアプリケーションの脆弱性について解説されました。

Welcart 1.9.3 のオブジェクトインジェクション脆弱性

Welcartは,WordPressをベースにショッピングサイトを構築する際に便利なプラグインで,国内でも非常に多く用いられています。はじめに,Welcartのフォーラムで,ユーザーからインシデント報告された様子を紹介しました。徳丸さんは,Welcart1.9.3と1.9.4の修正の差分を比較し,⁠外部入力(クッキー)をデシリアライズしている,典型的なオブジェクトインジェクションだ」と指摘しました。CMSやフレームワークのような柔軟のものほど起こりやすい脆弱だそうです。unserialize関数に信頼できない値(信頼境界を超えてきた値)を渡してはいけないと指摘しました。

画像

unserialize関数に任意の文字列を処理させることができる場合,攻撃者に都合の良いクラスのオブジェクトを生成させることができます。オブジェクトが生成されるとデストラクタを通ることになるため,オブジェクトが生成されてからバリデーション等をおこなっても手遅れです。とはいえ,シリアライズされた状態のままバリデーションを行うことも困難です。徳丸さんは,⁠外部入力を処理する場合は,JSONを用いることが有効である」と紹介し,やってはいけないことを知らずにやってしまったことが根本的な原因だと解説しました。

WordPress REST APIのコンテンツインジェクション脆弱性

脆弱性情報が公開されてから48時間足らずの間に,改ざんされたWebサイトの数は6万以上にのぼったそうです。認証なしにリクエスト一発でコンテンツを改ざんできる脆弱性を,実際にデバッガで追いかけながら解説されました。

脆弱性の原因は,存在しないコンテンツが指定された場合,update_item_permissions_checkメソッド(権限の確認)の様々なチェックをすべてくぐり抜け,メソッド最後のreturn文にてtrueが返されていたことが原因でした。

画像

認証不要で,極めて容易にコンテンツが改ざんできるため,深刻な脆弱性であることがわかります。

徳丸さんは,⁠この脆弱性は権限チェックの間違いの典型例です。権限のチェックと更新で,異なる入力を用いているわけですから,両者の不整合がチェック漏れの原因になります」と言及し,⁠入力値を使用する度に int にキャストしている箇所があり,これだ潜在的にバグや脆弱性の原因です」と述べました。

徳丸さんは以下のいずれかの方法で対処すべきだったと説明しました。

  • 入力値のバリデーションにて数値以外のものをエラーとする(推奨)
  • 入力時に整数にキャストし,以降の処理では一貫してキャスト後の値を用いる

WordPressのように,メジャーなアプリケーションでも起こった脆弱性なので,教訓として覚えておいてほしいと徳丸さんは話しました。

まとめ

今回,ケーススタディーで紹介された脆弱性のほとんどはバリデーションで防げたものでした。バリデーション(フォームバリデーション)で脆弱性対処ができるとは限りませんが,アプリケーションの前提条件を確認する意味でバリデーションは重要だと,徳丸さんは言います。

最後に,⁠バリデーションはしましょう。誤解されがちだが,私はバリデーションしなくていいとは言っていませんよ(笑⁠⁠」と,徳丸さんが締めくくったところで,ドッと笑いが起きました。

この講演の資料と動画は公開されています。どのような考え方をすればそもそも脆弱性が混入しなかったかという考え方を,実例をもとに知ることができます。非常にわかりやすいので,ぜひご覧ください。

著者プロフィール

田岡健人(たおかけんと)

PHPカンファレンス2017 レポート担当。PHPカンファレンスは2017年が初参加。奈良県出身。学生時代から一番好きな言語はずっとPHPのままです!