安全な脆弱性の作り方

この記事は 「脆弱性"&'<<>\ Advent Calendar 2016」16日目の記事です。具体的な脆弱性の話でなくてすみません。いろいろコードを書いていると、安全に脆弱性を発生させたくなるときがあります。って書くとさっぱり意味がわからないと思いますが、セキュリティの講義のための演習環境とかそういうやつです。

受講生自身の手でWebアプリケーションの脆弱性を探してもらうような演習では、検査対象となる脆弱性を含むWebアプリケーションを用意する必要があります。こういった「脆弱なWebアプリケーション」は例えば Broken Web Applications Project のようなものを代表にいくつかのものがありますが、これらはUIが英語であったり、あまりにもメジャーすぎて受講生も触っている可能性があったりと、場合によっては利用が難しいことがあります。特に、単一のWebサーバに対して複数の受講生が一斉に検査を行うような講義形態を採る場合(各自が手元でVMを立てて一人で検査を進めるよりも、同じサーバに全員でアクセスするほうが講義が盛り上がるのです)、環境に対して破壊的な脆弱性が存在していては演習そのものが中座してしまう可能性があります。

そこで、こういった講義を行う際には私はその講義の受講生のレベルなどに合わせて調整した脆弱なWebアプリケーションを都度自分で書いているのですが、そのときに「脆弱性があっても安全になるように」いくつか気を付けている点があります。今日はそういった点についてメモ書きとして記しておきます。

SQLインジェクションではデータベースを破壊できないよう読み取りのみに制限しておく
以前、演習の早い段階で参加者の一人がSQLインジェクションで他の参加者のパスワードを変更してしまったために他の参加者は演習を進めることができなくなったということがありました。それ以降は、SQLインジェクションを仕込むときにはデータベースの読み取りはできるが更新や削除といった破壊的な操作はできないように権限などを適切に設定する等の対策を行ってSQLインジェクションを含ませるようにしています。
CSRFは発生してもユーザーの妨げにならないものに限定する
以前の演習で、ログアウト機能にCSRFがある かつ ログイン直後に表示される個所で自由に画像ソースのURLを設定できる(これは脆弱性ではなくアプリケーションの機能) というのを組みあわせて、ログインすると直後に強制的にログアウトさせられてしまうという罠を参加者が仕込んだことがあり、その場合もやはり演習がそれ以降進まなくなってしまいました。ですので、CSRFを仕込む場合にはCSRFによって機能が呼び出されたとしても以降のユーザー操作に影響を与えない、例えばお問合せフォームの送信やニックネームの変更など、といった個所に限定するようにしています。
XSSCSRF同様にユーザーの妨げにならない個所に限定する
XSSを仕込んでおく場合も、CSRF同様に仮に悪用されてもユーザーの操作の妨げとならないような個所だけで発生するようにしておきます。例えば、XSSの発生する個所をユーザー操作の必要な個所に限定する、蓄積型のXSSであっても例えばそのメッセージを開く前に削除できるようにする、といった感じです。
OSコマンドインジェクションは入れない
OSコマンドインジェクションは環境を破壊してしまう恐れが強く、特に参加者がそのことを把握していないような場合には何が起こるかわからないので、基本的には脆弱性としては含ませないようにします。
セッションアダプションは積極的に採用
攻撃者の用意したセッションIDを利用者に強制させるセッションアダプションはユーザーによって回避可能であり操作不能となるようなことがないため、実装上無理がない限りは脆弱性として積極的に取り込んでいきます。
オープンリダイレクタも積極的に採用
たいていの場合、オープンリダイレクタも演習の妨げとなるような致命的な問題が発生しにくいため、積極的に組み込んでいきます。ただし、そのリダイレクタが永続的かつユーザーの操作なしに有効となってしまいユーザーが以降の演習ができなくなるといったような個所には絶対に含まれないように注意が必要です。
安全でない暗号
対象となるWebアプリケーションにそれっぽいセキュリティポリシーの文面を掲載しておき、例えばそこに「このサービスは通信経路上が暗号化されているため安心してご利用頂けます」等を記載しつつhttpでアプリケーションをサーブするといった、技術的でない脆弱性を含ませておきます。これは他の脆弱性と違い環境を破壊されないので安全であり安心してサービスを提供できます!

これ以外にも「HTMLコメントやJSコメントに機密情報(らしきもの)を記載しておく」といった小さな脆弱性を含ませることもあります。
それにしても思うのは、このような脆弱性を自然なかたちで作りこむのはそれなりに難しいのに、世の中のWebアプリケーションではもっと信じられないような脆弱性が普通に存在していたりして、一方でこれだけ頑張って安全に配慮して脆弱性を作っているにも関わらず、ちょっとしたバグを利用して Masato Kinugawa さんにサーバ上で電卓を立ち上げられてしまうことがあったりと、なかなか世の中難しいなというところです。