ダウンロード サンプルファイル (1.2 MB)
ASP.NET MVCのXSS対策 ~クライアントサイドでの防止方法~
前項では、XSS対策のフレームワーク側の設定について解説しました。次にビュー側に悪意を持ったスクリプトが渡されてしまった場合を考えてみます。シナリオの大前提として、コントローラクラス全体にValidateInput属性が宣言されている場合です。
サンプルでは予定動作として、テキストを入力後、表示ボタンを押すと同一ページの下部に文字列が表示されるページになっています。
しかし実際にはスクリプトが混入されてもそのままスクリプトが実行されてしまうサイトだとします(図2~3)。サンプルではアラートダイアログを表示するスクリプトを利用します。
大まかな流れとして次のとおりです。
- ビュー側のテキストボックスからスクリプトを注入
- コントローラ側でメッセージをビュー側に渡す
- ビュー側でスクリプトが実行される
それでは上記の現象が発生してしまうページのソースの確認をしてみましょう。コントローラ側の設定は次のとおりです。
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string message)
{
ViewData["Msg"] = message;
return View();
}
今回は特にデータチェックなどは行っていません。危険なデータが入っている可能性があるメッセージをそのままビューに返します。
続いてViewPage側の設定は次のとおりです。
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<form method="post" action="/Home/Index">
<h2><label for="message">メッセージを入力してください:</label></h2>
<br />
<textarea name="message" cols="50" rows="3"></textarea>
<br />
<%= ViewData["Msg"]%>
<br /><br />
<input type="submit" value="送信!" />
</form>
コントローラから渡された値をダイレクトに表示するように記述しています。
つまり、スクリプトがコントローラから渡されてきても、そのまま実行できる状態となっています(図3)。
本来はコントローラ側ですべて危険なスクリプトなどを検証できればいいのですが漏れる可能性があります。そんな時のために、コントローラ側から渡される値は第2回で紹介した、Html.Encodeメソッドを活用します(図4)。
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<form method="post" action="/Home/Index">
<h2><label for="message">メッセージを入力してください:</label></h2>
<br />
<textarea name="message" cols="50" rows="3"></textarea>
<br />
<%= Html.Encode(ViewData["Msg"])%>
<br /><br />
<input type="submit" value="送信!" />
</form>
Html.Encodeメソッドはパラメタとして渡された値をすべてエンコードするメソッドです。そのためパラメタとしてHtml文字列などが入っていても、すべてエンコードして出力されます。コントローラ自身がスクリプトの受け入れを許容していても、各アクションメソッドまで許容しているとは限りません。そんな時はHtml.Encodeメソッドを活用して値をエンコードしましょう。
ASP.NET MVCのCSRF対策
クロスサイト リクエスト フォージェリ(CSRF)と言えば4年経った今でも、はまちちゃんが某SNSにて世に知らしめた脆弱性のことと言った方が分かる方が多いのではないでしょうか? Webページ上でスクリプトやHTTPリクエストやリダイレクトを使って、ユーザーが意図していない操作を実行してしまう攻撃手法です。認証が必要なサイトであれば、ユーザーが持つ権限を利用することで削除や編集などを行うことができます。
このCSRF対策はコストは低くとも、ある程度の効果は見込めるので、ぜひ実装してください。設定方法は以下の2点を実行するだけです。
- ViewPage側にHtml.AntiForgeryTokenメソッドを記述する(トークンの生成)
- Controllre側でValidateAntiForgeryToken属性を設定する(トークンチェック)
AntiForgeryTokenメソッドは、hiddenフィールドとCookieにトークンを生成しValidateAntiForgeryToken属性を設定することで、リクエストを送ってきたユーザーがビューを表示させたユーザーと同一か、悪意を持った攻撃者でないかをトークンを利用してチェックしています(図5)。
トークンに対して何か処理を行うわけではないので、ソースは記述するだけです。
<h2>CSRF</h2>
<form method="post" action="/Home/CSRF">
<h2><label for="message">メッセージを入力してください(トークンチェック):</label></h2>
<br />
<textarea name="message" cols="50" rows="3"></textarea>
<br />
<%= Html.Encode(ViewData["Msg"])%>
<br /><br />
<%= Html.AntiForgeryToken() %>
<input type="submit" value="送信!" />
</form>
XSSのサンプルを流用しています。submitボタンの前にHtml.AntiForgeryTokenメソッドを記述するだけです。
[ValidateAntiForgeryToken()]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CSRF(string message)
{
ViewData["Msg"] = message;
return View();
}
コントローラ側では、利用したいコントローラまたはアクションメソッド前にValidateAntiForgeryToken属性を記述するだけなので、非常にお手軽です。
この設定はAjaxリクエスト時にも同じ方法になりますので、積極的に使用しましょう。
ASP.NET MVCのSQLインジェクション対策
SQLインジェクションは、動的にクエリをくみ上げるWebサイト上に悪意あるSQLクエリを注入することで、データの改ざんや削除などを行う攻撃手法です。
ASP.NET MVCにおけるSQLインジェクション対策は、ASP.NET 3.5 SP1以降で動作するフレームワークである点が挙げられます。つまり、基本的にデータアクセステクノロジにLINQを活用するという点です。LINQはSelectクエリのみをサポートしているのでデータの改ざんが行われる訳ではありません。また、実行コードはコンパイルが完了しているため、クエリの改ざんなどが行われないという保証がされています。
なぜLINQがSQLインジェクション対策になるのか詳しく知りたい方は『LINQ to SQLが通常のSQLより優れた選択肢である理由』を参照してください。
この記事は参考になりましたか?
- ASP.NET MVCフレームワーク 正式版 入門連載記事一覧
-
- ASP.NET MVCと周辺技術の活用テクニック
- ASP.NET MVCのセキュリティ対策とクライアントサイドスクリプト活用方法
- ASP.NET MVCの開発応用編1 ~リポジトリパターンをマスターする~
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
WINGSプロジェクト ナオキ(ナオキ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア




