VOYAGE GROUP エンジニアブログ

voyagegroup_techのブログ
VOYAGE GROUPエンジニアブログです。

security

Hardening ZeroというセキュリティイベントでMBSD賞を受賞しました。

4/21(土)に行われたHardening Zeroという全く新しいセキュリティイベントに参加し、三井物産セキュアディレクション賞をいただきました。
HardeningZero_MBSD賞



▼イベントの概要
ざっくり説明すると以下になります。
  • 全8チームによるチーム対抗戦
  • 1チームは2〜6人
  • 競技時間は8時間
  • 各チームはとあるECサイトの運営を委託される
  • 委託されたECサイトにはたくさんの脆弱性がある
  • 各チームは発見した脆弱性を必要に応じて修正する
  • 運営側が仕込んだインシデントが不定期に発生する
  • 競技終了後に4つの観点(売上、技術、顧客対応、インシデント対応)から採点される
参加者にはセキュリティ競技界隈では著名な方が多数いたらしく、軽くアウェー感を感じていたのは内緒です。


▼方針は「当たり前のことをやる」
このイベント自体が初めてであり、かつ僕らのチームのメンバーはセキュリティ競技に参加するのは全員初めてということで、競技対策というよりは普段当たり前にやってることをそのままやるという方針で挑みました。


▼メンバーと役割
僕らのチームは4名で参加し、以下のような役割で対応しました。
  • @makoga とりまとめ
  • @ajiyoshi プログラマ
  • @masaki925 インフラエンジニア
  • @Akiyah ECサイト管理者
各役割1人ずついれば何とかなるよねと思っていたのですが、思ったよりひどいサイトだったのでめっちゃ忙しかったですw
ただそのおかげ(?)で表彰式や懇親会では「4人であれだけ対応できたのはスゴイですね」と実行委員からお褒めの言葉をいただきました。:)


▼かんばんで情報共有
事前に決めてたわけではないのですが、当日@Akiyahが模造紙と付箋を持ってきてくれたので、会社で慣れ親しんだかんばんで円滑な情報共有ができました。
HardeningDay20120421

「チームで戦っている感じがすごく伝わってきました」や、「競技中に他のチームから見えるところに張り出すなんて斬新ですねw」など、他チームや実行委員からも好評でした。:D


▼競技の結果
ちょっとミスって売上はいまいちでしたが、それ以外は良い結果を残せたと思います。
Sales:                       511,728
Technical Merit:         1,700   1位
Customer Impression: 2,100   1位
Incident Response:     2,200   2位
HardeningZero_参加証明書

実は最初の途中結果発表では総合7位だったので午前中は少し焦ってました。まあ単なるイベントだしそんなに頑張らなくてもいいよねなんてことが頭をかすめましたが、メンバー全員が自ら考え、自ら動いたおかげで後半巻き返しができました。諦めたらそこで試合終了ですよね。


▼まとめ
Webサービスを堅牢にするためには、様々な視点と技術力が必要です。また、限られたリソースでどこから対応していくかのバランスをとることも重要です。
それらに対し自分たちがどのくらいできるのかを試してみるにはとても良いイベントと感じました。
秋くらいにはHardening Oneが開催されると聞いています。少しでも興味もたれた方がいれば、ぜひチャレンジして欲しいと思います。

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

前回のエントリ:アプリケーションハンガリアンを用いて徳丸本の「様々な列でのソート」のサンプルを改善してみた。を読んだ方から「わかりやすくなってなさすぎるw」という指摘をいただいたので補足します。

以下、いただいた指摘
  • 意図は伝わったけどs/usというprefixは一般的じゃないからパッと見てsafe/unsafeだと分からなかった。
  • SFromUSがsafe from unsafeの略とか分からなかった。
  • Joelのエントリ読んでやっと理解した。
そうですね。参考としてJoelのエントリ:間違ったコードは間違って見えるようにするへのリンクを記載するのではなく、まずこっち読んでねとしたほうが良かったかもですね。

伝えたかったことは、前回のエントリの繰り返しになりますが、外部から渡ってきた値を文字列連結で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;
}
その臭いを消すために外部から渡ってきた値はunsafeとし、safeに変換してから使うようにしました。これにより安全であることを分かりやすくしたつもりです。
$usSortKey = $_GET['sort_key'];                     // unsafeなprefixを持つ変数に格納
$sSortKey = SFromUS_SortKey($usSortKey);  // unsafeな値をsafeに変換し、safeなprefixを持つ変数に格納
$sSql .= ' order by ' . $sSortKey;                      // safeなprefixを持つ変数を連結
Joelは「どこか1行のコードでその間違いを見つけられる」ことが利点だと言っています。
$us = $_GET['name'];
これは正しい。

$usName = $us;
これは正しい。

$sName = $us;
これは間違っている。

$sName = $_GET['name'];
これは間違っている。

$sName = SFromUS($us);
これは正しい。

$sSql = ' order by ' . $_GET['name'];
これは間違っている。

$sSql = ' order by ' . $usName;
これは間違っている。

$sSql = ' order by ' . $sName;
これは正しい。

また、前回のエントリでは上記3行より関数の定義が先に記載されているのも分かりにくい原因だったかもしれません。

今回の議論で理解が深まった人がいれば幸いです。
今後もどこかの誰かに役に立つかもしれないことや、どこかの誰かが面白いと感じてくれるようなことを発信していきたいと思いますので、どうぞよろしくお願いします。

アプリケーションハンガリアンを用いて徳丸本の「様々な列でのソート」のサンプルを改善してみた。

こんにちは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;
これにより安全な値を連結していることが分かりやすくなったと思います。

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


記事検索
QRコード
QRコード