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

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

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

2017年10月8日,東京・大田区産業プラザPiOにて,PHPカンファレンス2017が開催されました。本稿では,ゲストスピーカーセッションであるEGセキュアソリューションズ株式会社 代表取締役 徳丸浩さんの講演「著名PHPアプリの脆弱性に学ぶセキュアコーディングの原則」をレポートします。

画像

著名なPHPアプリケーションでも脆弱性を狙った攻撃が絶えません。徳丸さんは「脆弱性対処の王道はプレースホルダによるSQLインジェクション対策のように,とにかく個別の脆弱性から守るための局所対策が大切。とはいえ,脆弱性対処を束ねる総論も必要だ」と言います。

今回の講演では,一般的なセキュアコーディングの原則,そしてPHPの著名アプリの脆弱性に関して,どのような考え方をすればそもそも脆弱性が混入しなかったのかを解説しました。

多くの脆弱性は外部からの入力が原因

はじめに,脆弱性の国際的な分類,CVE(Common Vulnerabilities and Exposures)とCWE(Common Weakness Enumeration)について説明しました。

CVEは個別ソフトウェアの具体的な脆弱性を識別する番号です。CVEの例として,WordPress REST APIの脆弱性(CVE-2017-1001000)⁠Apache Struts2 の脆弱性(CVE-2017-5638)を挙げました。CVE-西暦-連番で構成されるため,どの年の脆弱性かを一目見てわかるようになっています。

CWEはSQLインジェクション(CWE-89)やディレクトリトラバーサル(CWE-22)といった脆弱性の種類を表します。IPAでよく使われるCWEを分類し階層的に表した構造図を示し,多くの脆弱性は,外部からの入力値の扱いに起因していると指摘しました(不適切な入力確認:CVE-20)⁠

画像

またJPCERTのJava セキュアコーディングスタンダード(CERT/Oracle版)では「入力値検査とデータの無害化(IDS00-J)⁠の項において⁠信頼境界を超えて渡される信頼できないデータは無害化する⁠と言及されていると紹介しました。つまり,多くの脆弱性が外部からの入力が原因になっていて,それを無力化せよ,という一般的な指針を示していると解説しました。

典型的な脆弱性と信頼境界の関係

プログラムソースや設定ファイル,データベースに記述されているものは無条件に信頼して良いため,プログラムやSQL文の実行に脆弱性が入る余地はないそうです。例として,信頼境界の中で閉じた処理(固定のSQL文を実行する)を取り上げました。仮に局所的な問題があっても攻撃経路が存在しないため,外部から攻撃されることはないと強調しました。

画像

一方で,信頼境界を超えて外部からの入力を元にSQL文を組み立てる場合,徳丸さんは「信頼境界の外に出た値は信頼できない。信頼が必要な値は⁠信頼境界から外に出さない⁠で用いるように」と呼びかけました。

続いて,典型的な脆弱性であるSQLインジェクション・ディレクトリトラバーサル・認可制御不備・セカンドオーダーSQLインジェクションを例に,信頼境界との関係を説明しました。簡単に言うと,信頼できない値はプレースホルダなどを使い安全な形で呼び出しをすれば良いということです。先に取り上げたIDS00-Jの見出しからも⁠信頼境界⁠⁠信頼できない”,⁠無害化⁠という言葉が消え,⁠SQLインジェクションを防ぐ」に改訂されたそうです。

理想は,脆弱性がないことが一目で分かること

では,信頼境界は無意味なのでしょうか? 徳丸さんは「そうではない」と述べ,hiddenパラメーターでSQL文を渡している値を2つに整理しました。⁠どんな値でも安全に使える方法があるもの」「値を信頼するしかないもの」です。

どんな値でも安全に使える方法があるものとして,SQLクエリに文字連結を用いず,プレースホルダを用いること。そしてHTML表示の際にもれなくエスケープ処理を行うことを挙げました。 値を信頼するしかない例として,SQL文,プログラムコード,ログインユーザー名を挙げました。

徳丸さんは,脆弱性対処が局所化できる場合はそれがベストだとし,⁠どんな値でも安全に使える方法がある場合は淡々とその方法をやること」と述べました。例えば,ヘッダインジェクションが発生しないライブラリや,PHP最新版を使うことなどが本質的な解決手段とも話していました。

そして,信頼された値が要求される場合は,信頼が必要な値を「信頼境界から外に出さないで用いる」ことを強調していました。なぜなら信頼境界の外に一度出た値は,いくらバリデーションをしても信頼できる値ではないからです。徳丸さんは「信頼されたデータ」が必要な例として,プログラムコード,SQL文,evalの入力,設定ファイル名に記載されたファイル名,正規表現,オブジェクトを挙げました。

画像

ただし,認証・認可によって「信頼できることを確認する」ことは可能だと徳丸さんは補足しました。phpMyAdminにおけるSQL文の呼び出しを例に,認証(ログイン済みユーザー)⁠認可(権限を与えられたユーザー)を説明し,認証・認可によって信頼ができるケースについて解説しました。

著者プロフィール

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

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

コメント

コメントの記入