セキュリティ・キャンプ2014応募用紙を公開します #seccamp

どうやら応募用紙に書いた内容を公開しても問題ないようなので、載せようと思います。

さすがにそのままは恥ずかしいので、要約しますが・・来年以降、応募される方々の参考になれば幸いです。 つっこみも期待しております。

記述内容

1. このクラスを希望した自分なりの理由を教えてください。また、この講義で学んだことを何に役立てたいかを教えてください。(選考上もっとも重視します)

  • Webサービスの開発をしたこと
  • セキュリティ系のコンテストに参加したこと

上の2つの経験から学んだこと、それが自分のセキュリティに対する意識にどう影響し、応募に至ったのか。

参加したらどうしたいのかについては、まあ、ありきたりな感じ。

2. Webに関連したプログラミング歴を教えて下さい。また、今までに作ったWebに関連したプログラムがあればどのようなものを 作ったのかを、あるいは将来どんなシステムを作ろうと思っているのか、差し障りのない範囲で具体的に教えてください。

【Web関連のプログラミング歴】
サーバサイド

  • Ruby ~1年
  • MySQL ~1年

クライアントサイド

  • HTML/CSS 2~3年
  • JavaScript ~1年

経験浅い・・

【今までに制作したWeb関連のプログラム】

簡単な説明を添えて。

【作りたいシステム】
企業が作ってるやつみたいなスマートフォンアプリ〜Webまでを網羅するサービス(?)。全てを一貫して制作してみたい。けど、明確なアイデアは今のところはない。

3. クロスサイトスクリプティングあるいはSame Origin Policyについて自分の言葉で語ってみてください。(これらがどのような脆弱性・技術かの解説は不要です)

XSSってなんでまずいのか、いまいち分かりづらい。XSSの体験コンテンツとかもっと工夫しないとだめ。興味持ってる人がやってみても、問題の重要さに気付けない=実際の行動に結び付られない。これは勿体無い。

「あるいは」とのことだったので、Same Origin Policyについては触れなかった。

4. User-Agentを偽装するということについて、(1)実際に試した方法、(2)偽装されていることを判別する方法、(3)実際に偽装したことがあればその目的 の3点について自由に書いて下さい。

なぜだか頭の中が完全に『UA偽装=PC→スマホのUA偽装』っていう思考になってしまっていて、それだけしか考えてなかった。

【実際に試した方法】
Google Chrome付属デベロッパツールのエミュレーション機能

【偽装されていることを判別する方法】
調べたらJavaScriptのnavigatorオブジェクトを使ったら良いっぽい。実際にJavaScript書いて検証。

  • エミュレータで実行した場合の結果
  • 実機(スマートフォン)で実行した場合の結果

を比較してみると、確かに誤魔化しきれてない部分がある。これを使えば、クライアントサイドでのUA偽装チェックは行えそう。
その他にも、JavaScriptのtouchイベントとかIPがキャリア保有のやつかどうかとかも使えそう。

【実際に偽装したことがあればその目的】
偽装したことがある。目的は、スマートフォンからアクセスしか許されていないWebサービスをPCから利用するため。

5. 以下のJavaScriptのコード断片は、とあるWebサイトで利用されていたものです。これを見て気付いた点について、自由に書いてください。

function getRedirectPageUrl(){  
    var url = location.hash.substring(1);
    try{
        if( url.length === 0 ) return "/";
        url = decodeURIComponent( url );
        if( !url.match( /^https?:\/\// ) ) return "/";
    }catch( e ){
        console.log( "invalid url" );
    }
    return url;
}

/* .... */

var url = getRedirectPageUrl();  
location.href = url;

まずは、JavaScriptの挙動について。

2行目: location.hashは現在のURLの"#"以後の文字列を取得、substringで"#"を取り除いた文字列が変数urlへ代入される
4行目: 変数urlの長さが0、つまり“#”以後の指定がなければ"/"を返す
5行目: 変数urlをURLエンコードから通常の文字列へデコードする
6行目: 5行目で変換した変数urlが"http://"または"https://"で始まる文字列でなければ"/"返す
15行目: 関数getRedirectPageUrl()を実行し、返り値を変数urlへ代入する
16行目: 15行目で取得したURLへ遷移する

次に、実際にこのコードを実行してみて気付いたことと問題点。

  • 6行目の正規表現によって、スキームがhttpまたはhttpsに限定されているため、XSSは発生しない。
  • 一方で、オープンリダイレクトを発生する。

そして、問題の原因と解決策の提案。

更新: 2014/06/23
decodeURIComponent()関数の挙動の関係で、#以後に%単体のみの文字列が入った場合に、XSSが可能になるみたいです。

【原因】
オープンリダイレクトを発生する原因は、

  • 外部からリダイレクト先URLの指定ができること
  • リダイレクト先URLのドメインのチェックが甘いこと

実際に、
http://example.jp/#http://google.com
みたいなURLを指定すると、任意の外部のWebサイトへのリダイレクトに成功。

【解決策の提案】
自サイト内のリダイレクトのみを扱うのなら、6行目の正規表現を、
/^https?:\/\// → /^https?:\/\/examplpe.jp\/[a-zA-Z0-9.\/-#]*/
などとすると良い。
事前にリダイレクト先URLのリストを持っておくのも一つの手。

最後に、今思えば的外れな気付きを補足。

このコードを含むWebページをドメイン名のみのURL(表現?)に配置した場合(例: http://example.jp/)、そのページへのアクセスを行うと無限ループを引き起こす。4行目の返り値を、
“/“ → “/#top”
のような何かアンカー名の付いた値へ変更すると良い。

この辺の参考には、セキュキャン結果発表の直後に(!)@ITに掲載された、はせがわ先生の書かれた記事を読むと良いと思います。

6. そのほかアピールしたいこと、書き足りないことがあれば自由に書いてください。

セキュリティ・キャンプへの熱意は、設問への回答に全て込めたつもり。

とか、くさいことを書いた。(特に書くことがなかった・・)

考察

合格の決め手を自分なりに考察してみると、やっぱり

  • セキュリティを学ぶ必要性を感じている理由をしっかり述べたこと
  • 課題を解くために、手を動かしたこと(検証、考察)

の2点が大きかったのかなあ。講評を見てみても、講師の方々も手を動かすことが大事、と言っておられますし。

以上、セキュキャンの応募用紙を公開してみましたー。

kosk

へっぽこ