先日、GitHubはRuby on Railsのmass assignment機能の脆弱性を突かれた。この脆弱性は数多くのRubyベースのサイトだけではなく、ASP.NET MVCや他のORMフレームワークを使用したサイトにも影響を及ぼす可能性がある。
mass assignment自体は、フォームデータをオブジェクトにマップするための安全かつ効果的な機能だ。同様に、ASP.NET MVCで同等の機能であるデータバインディングも単独で使用する分には安全な機能だ。この脆弱性が実際に問題となるのはmass assignmentとORMを不用意に併用した場合だ。
具体的にそのシナリオを考えてみよう。データベースに“user”というテーブルがあり、このテーブルには機密データと非機密データの両方が混在しているとする。おそらくこのテーブルにはユーザの表示名、メールアドレス、ユーザの管理者権限などのカラムがあるだろう。表示名とメールアドレスの変更を許可する画面を構築する場合、まずRailsまたはMVCのスキャフォールディング機能を使用してドメインオブジェクトやビューそのものを自動生成し、次にユーザによる変更が不可のフィールド(“Is Administrator”チェックボックスなど)をそのビューから削除することで実現できる。
このときドメインオブジェクトからIsAdministatorプロパティを削除し忘れるとセキュリティホールが作成され、mass assignmentやdata binderによって正規の変更とともにそのプロパティが更新される。その後レコードが保存されると、ORMライブラリにはそのまま新しい値が格納される。
この問題の妥当な解決策として次の3つが挙げられる。
- mass assignment/data binderが更新対象外のプロパティを無視するようにフラグを設定する。
- ビジネスオブジェクトで実際に使用していないプロパティは完全に削除する。
- 更新リクエストの受信専用モデルを作成し、ORMオブジェクトやストアドプロシージャコールに手動でマップする。
今回の脆弱性は新たに発見されたものではない。mass assignmentに関する注意事項は、4、5年前の“ハッカーが好むMass Assignment(Hackers Love Mass Assignment)”や“attr_protectedを使用しないとハッキングの対象になる(Use attr_protected or we will hack you)”などの記事から簡単に見つけられる。今回異なる点はただ一つ、被害が大きく取り沙汰されたことだ。