はじめに
ASP.NET MVCはASP.NET 3.5ベースですので、ASP.NET MVC固有のセキュリティ対策や、スクリプトの利用についても基本的に意識する部分は少ないです。
しかし、フレームワークとしてどのような対策が行われているか気になる方も多いかと思います。今回はASP.NET MVCが提供しているセキュリティ対策と、ASP.NET MVCアプリケーション上でASP.NET AJAX Control Toolkit(以下、Control Toolkit)を利用する際のコツを紹介します。
必要な環境
次の環境が必要です。
- Visual Studio 2008 SP1
- ASP.NET MVC RTW版
- ASP.NET AJAX Control Toolkit(Scriptファイルのみ)
Visual Studio 2008(以下、VS2008)のインストールはVisual Studio 2008徹底入門 第1回を、VS2008 SP1のインストールは『簡単なデータ編集はお任せ! ASP.NET Dynamic Dataアプリケーション 』を参考に行ってください。
ASP.NET MVC RTW(Release To Web)は、Microsoft Download Centerからダウンロードできます。インストールはウィザードに従って進めるだけです。
また、本稿の後編で利用するControl Toolkitはサーバーコントロールを利用しません。Scriptファイルのみの「AJAXControlToolkit-ScriptFilesOnly.zip(バージョン30512を使用)」がControl Toolkitダウンロードページで提供されていますのでダウンロードしておいてください。
最新版としてリリースされている、30930では本稿のサンプルが動作しませんのでご注意ください。
今回触れる内容
今回触れるのは、以下の部分です。
- ASP.NET MVCにおけるセキュリティ対策
- ASP.NET MVCとControl Toolkitの活用
ASP.NET MVCそのものについては過去の内容も併せて参照してください。
- ASP.NET MVCフレームワークの概要を理解する
- ASP.NET MVCで簡単なアプリケーションを構築しよう
- ASP.NET MVCで認証、テスト、フィルタ機能、AJAXを活用しよう
- ASP.NET MVCの開発~リポジトリパターンをマスターする~
ASP.NET MVCのセキュリティ対策
ASP.NET MVCはWeb技術ですので、当然フレームワーク側で多くのセキュリティ対策が取られています。また、ASP.NETが根底にある技術でもあるので基本的にASP.NETのセキュリティ対策が扱えます。しかし、細かな点で差異などが発生しているため、本項ではASP.NET MVCにおけるセキュリティ対策について紹介します。
ASP.NET MVCのXSS対策
最初にご紹介するのはASP.NET MVCのXSS(クロスサイトスクリプティング)対策です。XSSと言えば、クライアントサイドから悪意あるスクリプトを混入させてユーザーを意図しないページへ誘導したり、セッションハイジャックりする攻撃手法として知られています。
ASP.NET MVCのXSS対策 ~既定の設定と設定の回避方法~
XSSが起こりやすいケースとして、テキストボックスにスクリプトを埋め込まれて実行されるパターンが多いですが、ASP.NET MVCではASP.NET Web Form同様に、既定の設定で「< 何らかの文字列 >」が書かれている値がサーバーに送られそうな時には、HttpRequestValidationException例外が発生します(図1)。
これは、XSSが発生しそうなデータをサーバー側に送り込ませないように事前検証する機能です。非常に簡単なXSS対策です。
しかし、実際は意図的にサーバーに送らせたい場合もあります。例えばブログなどで使われているRichTextBoxのHtml文字列などの場合です。意図的に送りたい場合でもExceptionが発生してしまいます。
ASP.NET Web Formでは、ページ ディレクティブ上またはWeb.configファイルの<pages>セクション内にて、ValidateRequest属性をfalseに設定すると回避できましたが、ASP.NET MVCでは回避できません。ASP.NET MVCではコントローラ側でValidateInput属性をfalseに設定することで例外を回避できます。
[ValidateInput(false)] public class HomeController : Controller { public ActionResult Index() { (中略) } (中略) }
ValidateInput属性は、他の属性同様にコントローラクラス自身、または個別のアクションメソッドに設定できます。
この場合データのチェックはコントローラ側でしっかりと行う必要があります。認証ユーザーのみにしか適用しないのはもちろん、他にもデータの検証を行う方法などを検討しなくてはいけません。
Html文字列の検証を行う例として、携帯サイトで使われているホワイトリスト方式を使うことができます。
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Index(string message) { // クライアントからの値をエンコードする string ValdateString = Server.HtmlEncode(message); /// 許可数するHTMLタグの分記述する /// 今回は<b></b>/<br />/<p></p>を許可 ValdateString = ValdateString.Replace("<b>", "<b>"); ValdateString = ValdateString.Replace("</b>", "</b>"); ValdateString = ValdateString.Replace("<br />", "<br />"); ValdateString = ValdateString.Replace("<p>", "<p>"); ValdateString = ValdateString.Replace("</p>", "</p>"); // 加工が終わった値をViewDataに格納する ViewData["Msg"] = ValdateString; return View(); }
最初にサーバー側で、HTMLEncodeを行い、許可するタグだけ置換していく方法です。
上記コードでは、Server.HtmlEncodeメソッドでパラメタの値をすべてエンコードし、Html文字列として許可しているタグだけをReplaceメソッドで置換していきます。
ホワイトリスト形式では、許可するタグの分の記述が必要になるので、コードが冗長になりがちです。そのような場合は、正規表現を使うことも検討しましょう。