これは VOYAGE GROUP エンジニアブログ:Advent Calendar 2014 の 17 日目のエントリです。
VOYAGE GROUP では もの創り実践プログラム Treasure というエンジニア向けインターンシップを開催しています [1] [2] 。
Treasure 全体の様子は既に VOYAGE GROUP エンジニアブログにて 前編 と 後編 に分けて紹介されていますが、このエントリでは、前半パートにおいて僕が担当した Web セキュリティに関する講義についてお話ししていきます [3] 。
講義は休憩や実際に手を動かしてもらいつつで 3 時間半という長丁場でしたが、なぜか随所で笑いが巻き起こる状態で非常に評判がよく、同じ内容を 独立した 1 day インターンシップとして京都でも開催 させていただけました [4] 。これもひとえに必死に内容に食らいついてくれたインターン生のみなさんのおかげなのですが、講義資料自体は非常に堅苦しいもので特に奇をてらったということもなく、なんであんなに盛り上がったのか自分でも不思議でなりません。
ありがたいことに Treasure の講義中はうちのクルーも忙しい業務の合間をみて見学に来てくれていて、なにやら Slack で実況的なことがされていました。そのなかに端的に講義の様子を伝えてくれそうな発言があったのでご紹介します。
講義の概要
さて、簡単に講義の流れを説明すると、以下のような感じです。
- 情報倫理
- 情報セキュリティに関する法律や、近年のセキュリティ事案についてなど
- Web のセキュリティ脆弱性に関する概要、攻撃手法、対策手法に関する講義 (実習つき)
- いくつかのパターンの XSS 脆弱性 [7]
- SQL Injection 脆弱性
- CSRF 脆弱性
- クリックジャッキング脆弱性
- (補遺として) セッション管理に起因する脆弱性など、その他の脆弱性
個別の Web セキュリティ脆弱性についての講義では、攻撃手法については一応学んでもらうものの、主として対策方法を身につけてもらうような形で進めました。実習環境 [8] に存在する脆弱性のそれぞれについて、自分たちで対策方法を考えて修正してもらうようなカリキュラムとなっています。
おそらく「情報セキュリティそのもの」や「情報倫理」に関するトピックをなくすことでより多くの脆弱性についてカバーできたのではないかと思います。あるいは、もっと本格的にサービスを攻撃し合うような競技仕立てのプログラムにもできたでしょう。それはそれで有意義ですし、きっと知的好奇心を刺激する楽しい催しになったはずです。
なんでそうはしなかったか、ということについてつらつらと書いていきたいと思います。
講義のねらい
そもそもは Treasure のプログラムの一部として組まれた講義なので、根本の目的はもちろん Treasure のそれと一致しています、が、実は、僕のなかにはほかにもいろいろな野望がありました。いままで内緒にしていた野望です。本邦初公開です。
- 情報セキュリティを身近に感じてほしい
- 「ふつうの」Web アプリケーションプログラマとしての知識を本質から理解してほしい
- 自覚なしに法を犯さないようにしてあげたい
正直なところ、個々の脆弱性対策手法等の技術的な内容よりも、これらのトピックについてどうやってちゃんと伝えられるかが苦心したポイントです [9] 。
「情報セキュリティを身近に感じてほしい」
大げさに、そして大ざっぱに言ってしまえば、我々の仕事はインターネットをはじめとしたコンピューティングの世界をよりよいものにしていくことです。Treasure は「もの創り」を前提にしたカリキュラムとなっていますから、実際にそうした仕事の一端に触れることができます。
しかし残念なことに、よりよい世界を作れば作るほど、よりよいサービスを出せば出すほど、攻撃者からみた「旨み」も多くなっていくものです。自分がソフトウェアエンジニアとして世の中にいい影響をもたらそうと思うのであれば、情報セキュリティに関しても決して他人事ではいられません。
そうは言ってもセキュリティとは面倒なものです。できるだけ寄りつきたくないというのが本音であろうとは思います。これはもうそういうものだと素直に白状したうえで、それでも身近に感じてもらえるように心がけました。
まず、自分の周りで起きた情報セキュリティ事故についてディスカッションしてもらうことにしました。
こんなふわっとしたお題でディスカッションになるかなーなどとほんのり心配だったのですが、さすが情報化社会というか、最近の若者はデジタルにネイティブしていることもあって、大学内システムのあれこれであったり、自らのメールアカウントに不正アクセスがあった話など、非常に生々しいエピソードが聞こえてくることもありました。
それから更に世の中全体に視野を広げて、世間で起きた過去のセキュリティ事故に関して事例をたっぷり交えて解説しました (2005 年から 2014 年まで)。
ほかにも、個々の脆弱性解説の場面で実際に僕が見つけた脆弱性に関する話題を盛り込んだりと、「現実の話をしているんだよ」という点についてはできるだけ強調するように心がけました。
「『ふつうの』Web アプリケーションプログラマとしての知識を本質から理解してほしい」
Treasure は「もの創り」を主眼に置いたプログラムで、セキュリティエンジニアを育成することを意図してはいません [10] 。ではこの講義の役割とはなにか、といえば、あくまで security-aware なプログラマを育成することです。
では security-aware なプログラマとはなにか? 人それぞれ考え方があるでしょうが、僕は、あたりまえのことをあたりまえにできる、ふつうのプログラマだと思っています。
Web アプリケーションを開発するにあたって、テキストベースのプロトコルは切っても切れない関係です。同様にして、テキストベースのプロトコルにおいて、インジェクション系脆弱性の可能性もまた切っても切れない関係にあります。
京都での講義ではまず、この点について触れることにしました。
そのうえでエスケープという手法の存在について触れます。
ここには htmlspecialchars() も 0 OR 0 = 0; -- も出てきません。
基本的にテキストフォーマットは構文を持ち、文脈を持ち、そしてその文脈上意味のある表現を許すことで意図しない構文の破壊がおこなわれるというバグの解説でしかありません。単にこの種のバグにはこういう風に気をつけてちゃんとコーディングしていこうね、という話です。しかしこれこそが、この種のテキスト操作をするにあたってもっとも身につけておかなければいけない基本的な知識だと考えます。
入力をそのまま出力しないようにしましょう、 HTML に動的な値を埋め込むときには htmlspecialchars() を使いましょう、といった、ある種小手先とも言える知識を単に教えるだけというのは簡単です。教える方もそうですし、教わる方にとってもたぶんそうです。しかし世の中にはさまざまなテキストフォーマットが存在します。さまざまなコンテキストが存在します。そのフォーマットには確立されたエスケープ手法が存在しないかもしれません。というよりあなたが独自のフォーマットを作るかもしれません。いまはそのときはよくても場当たり的な知識だけでこの先プログラマとしてやっていくのは難しいでしょう。
インジェクション系の攻撃においては、こういうとき、構文の破壊を引き起こさないように、仕様に従った「ふつうの」プログラミングをしていれば防ぐことができます。だから僕はセキュリティのことについて教えているようでいて、実際にはよりよいプログラミング作法について教えていたも同然なのです。
そういう前提のもと、 XSS について理解するには、構文についての知識が必要ですし、
エスケープ手法に関する知識も必要です。
攻撃の結果、どういう影響が文章構造に及ぶかというのも知っておかなければなりません。
もちろんスクリプトの実行コンテキストに関する理解も必要です。
複数の文脈を含有する場合の処理の難しさについても知っておく必要があります。 Vue.js のデータバインディング構文を含む HTML モドキを PHP で動的に構築して出力するなんてもってのほかですね。
こういうことをひたすらにコツコツやろうとした結果、膨大な講義資料と、 Treasure 用講義資料は 136 ページ、 1 day インターン用講義資料は 186 ページという大ボリュームになってしまいました。はじめる前は不安で仕方がなかったのですが、実際にはなんとか受け止めてもらえたようで一安心です。
「自覚なしに法を犯さないようにしてあげたい」
唐突にポンと出てきたトピックですね。法? Treasure で? エンジニア向けインターンで?
この話題を取り上げたのは完全に僕のわがままです。学生にセキュリティを教えるにあたって、どこかで誰かが教えなければならないことだと前々から思っていたので公私を混同してみたという感じの経緯です。
Treasure では少なからずセキュリティ脆弱性に対する攻撃手法を伝えます。本当に基本的なものでしかありませんが、悲しいかな、現実問題として、そのくらいの知識であっても簡単に攻撃ができてしまうほどに、この世の中は脆弱なシステムで溢れています。
自分の得た知識がちゃんと現実でも機能するというのは嬉しいものです。「え、まさかこのサイトにこんな?」という脆弱性を見つけたとき、「これは大変なものを見つけてしまった」という感情と一緒に、一種の楽しさ、喜びのような場違いな感情がわき起こってしまうかもしれません。そういったサービスに対して、上から目線で問題を指摘してみたり、Twitter 等で晒して注目を浴びるというのもきっと楽しいことでしょう。もしくは、そのサイトのため、あるいはユーザーのため、もしかしたら自分の利益のためにその脆弱性に対する有効な攻撃をしてみたくなるようなことがあるかもしれません。
学生といってももう立派な大人です。大人としての、自らの確固たる信念と覚悟に基づいてそういう行動を取ることについて、たぶん僕には止めることができません。社会が止めてくれるに任せるしかありません。
けれども、残念ながら、「(そこまで) 悪いことだと知らなかった」がためにやり過ぎてしまうケースも散見されます。そういう事件を知ったとき、見かけたとき、「これはよくないことなんだよ」と周りの人が教えてくれていたらよかったのにと心を痛めずにはいられませんでした。
そういうことで、あまりにも心を痛めすぎて、とうとう自分が出張ってでも「これはよくないことなんだよ」という役割を担う機運だと思ってえいやと講義に組み入れてしまったという次第になります。まあ、なんというか、いい形で伝わっていれば幸いですというほかないですね。
来年どうしましょう
日々挑戦を続けていく我々として、来年も僕が講義をやったり、 Web セキュリティのカリキュラムがあるとも、 Treasure がいまのフォーマットのままで開催されるとも限りませんが、まあだいぶ寒い時期に差し掛かってきましたし、渋谷では最近雪も降りました。ここで鬼に嗤ってもらうのもまた一興でしょう。
少なくともこのエントリで具体的に書いてしまった内容についてはそのままでは使いづらくなってしまったので、自らハードルを上げてしまった感じはあります。ただ、僕は少々 M 気質なのでこれは仕方のないことです。
講義の理解度にバラツキが見える、そもそも僕がしゃべりすぎているなど、おおいに改善の余地はあると思っているので、実習の密度を増やしたりしつつ学生ともう少しコミュニケーションを取れるような性質の講義に変えていけないかなあなどとぼんやりと考えたりしています。
Treasure のほかの講義等の内容とすりあわせて [11] みたいなところはあるのですが、個々の対策技術よりもセキュリティを考慮した設計周りのトピックを設けてもいいかもしれないとか、逆に京都でおこなったような種類の 1 day インターンではもう少し競技的な要素を取り入れてもいいかもしれないとか、まだまだ工夫の余地は残されていそうなので、今年よりももっとレベルアップした講義を展開できるようにいまから頭をひねっていきたいと思います。
おしまい
ということで VOYAGE GROUP エンジニアブログ:Advent Calendar 2014 のなかではちょっと異色な感じのエントリでお送りいたしました。いかがでしたでしょうか。みなさんの会社でのインターンシップの参考に……されすぎるのも我々としては少々困るかもしれないところではあるのですがw、出来のいいプログラマが各所で育っていくこと自体は業界にとってとても意義のあることだと思うので、ひとつお手柔らかにお願いしますといったところですね。
さて、明日は我らが大スター @suzu_v さんです! ご期待ください!
[1] | 他にも VOYAGE GROUP では多種多様なインターンを開催しています。詳しくはインターンシップ特集ページ http://voyagegroup.com/internship/ をご覧ください。 |
[2] | 実は応募ページを確認していなかったので今更気がついたのですが、本稿執筆時点で HTTP の http://voyagegroup.com/internship/ 上で https://mypage.1000.i-web.jpn.com/voyagegroup2016/ に誘導していてとてもよろしくないですね。本件については関係者に連絡したうえで是正するように申し伝えます。僕がついていながら大変申し訳ありません!!! |
[3] | 大人の事情で資料は公開できません。 |
[4] | こちらは Treasure の他の講義を前提としていないこともあり、多少増補して 5 時間でした。 |
[5] | 現実のプログラミング時に CIA を意識することはあまりないかと思うので扱うべきかどうかは悩みどころだったのですが、セキュリティ関連書籍はもちろん、 RFC や Internet Draft を読み込むなど、「ちゃんと」開発をするための入口となる知識であることは間違いなく、まさに Treasure はその入口をも提供するプログラムであるので触れることにしました。 |
[6] | リスクについて様々な対応方法が存在すること、コストと天秤にかけて選択するべきであることを認識するのは重要だと思っています。 |
[7] | もちろん DOM Based XSS も含みます。 |
[8] | 講義のためにこしらえたオリジナルの実習環境で、 SQL Injection や複数種類の XSS 脆弱性、 CSRF 脆弱性について学べるように作っています。 |
[9] | 先述の通りメインで扱う内容は対策側のもので、ある程度理論や手法が確立されているものばかりですから、技術面の解説はそれほど難しいということはありません (単純に分量の問題はあったものの)。 |
[10] | もちろん、この講義をきっかけとしてセキュリティエンジニアが育っていくのであればこれほど嬉しいことはありませんが、きっかけを担うくらいが限界かなとは思います。 |
[11] | 今回であれば講師の一人である @brtriver さんが Vue.js をチョイスしたのに合わせてこちらの講義の内容をチューニングしたりといったこともしています。 |