こんにちはCTOの小賀(@makoga)です。今回はアプリケーションハンガリアンを用いて徳丸本のサンプルコードを改善してみます。

--------------------------------------------------
2011/9/22に補足エントリ書きました。
『アプリケーションハンガリアン...改善してみた』のエントリが「わかりやすくなってなさすぎるw」と指摘いただいたので補足します。
--------------------------------------------------

要約

  • 基本的にSQL文を動的に組み立てない。極力やらない方向で考える。
  • どうしても動的に組み立てたいときは、外から渡ってきた値は安全ではないので直接使わない。
  • 安全な値とそうでない値はアプリケーションハンガリアンを用いて可読性を高める。

詳細

弊社では現在徳丸本こと体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践の勉強会が3つ進行中です。その中の1つで「4.4 SQL呼び出しに伴う脆弱性の様々な列でのソート」のサンプルコードをもう少し改善できるよねという話になりました。
$sort_columns = array('id', 'author', 'title', 'price');
$sort_key = $_GET['sort'];
if (array_search($sort_key, $sort_columns) !== false) {
    $sql .= ' ORDER BY ' . $sort_key;
}
上記が136ページに記載されているサンプルコードですが、以下のような改善点があると思います。
  • GETで渡された値をSQL文に連結しているので、パッと見てこのコードが安全か分かりにくい。
そこでアプリケーションハンガリアンを用いて以下のように改善しました。

function SFromUS_SortKey($usKey) {
    $SFromUsSortCol = array(
        'sort_id' => 'id',
        'sort_author' => 'author',
        'sort_title' => 'title',
        'sort_price' => 'price' );
    if(array_key_exists($usKey, $SFromUsSortCol))
    {
        $sSortKey = $SFromUsSortCol[$usKey];
    } else {
        $sSortKey = 'id';
    }
    return $sSortKey;
}
$usSortKey = $_GET['sort_key'];
$sSortKey = SFromUS_SortKey($usSortKey);
$sSql .= ' order by ' . $sSortKey;
これにより安全な値を連結していることが分かりやすくなったと思います。

参考:間違ったコードは間違って見えるようにする