ここでは、ASP.NET がクロスサイトスクリプトに対して行っている制限について検証しています。
スポンサーリンク
System.Web.HttpRequestValidationException
asp:TextBox コントロールに以下のような HTML ソースやスクリプトを入力してポストバックを行うと System.Web.HttpRequestValidationException 例外が発生します。
テキストボックスに入力する文字列
- <p>string</p>
- <script>alert(‘string’);</script>
などなどです。
[ 発生する例外 ]
危険な可能性のある Request.Form 値がクライアント (TextBox1=”<p>string</p>”) から検出されました。
説明: 要求の検証により、危険性のあるクライアント入力値が検出されました。要求の処理は中止されました。この値は、クロス サイト スクリプト攻撃などのアプリケーションのセキュリティ問題を引き起こす可能性があります。ページ ディレクティブか、 構成セクションの validateRequest=false を設定することによって要求の検証を無効にできます。しかしこの場合、アプリケーションですべての入力を明示的に確認することをお勧めします。
例外の詳細: System.Web.HttpRequestValidationException: 危険な可能性のある Request.Form 値がクライアント (TextBox1=”<p>string</p>”) から検出されました。
この動作は、上記のようにユーザーが入力したスクリプトの実行を防ぐために、セキュリティ上の理由から発生するデフォルトの動作です。
例外を発生させないようにする
例外を発生させないようにするには、web.config に、<pages validateRequest=”false” /> を追加します。
web.config
<configuration> <system.web> <pages validateRequest="false"> </pages> </system.web> </configuration>
これで、HTML ソースやスクリプトもそのままテキストボックスに文字列として 表示されるようになります。
Label コントロールの場合
テキストボックスの場合は問題なく文字列として表示されるようになりました。しかし、テキストボックスコントロールをラベルコントロールに変更すると、HTML ソースをブラウザで表示した結果が表示されたり、ユーザー入力のスクリプトがそのまま実行されてしまいます。
このように開発者が意図しないようなスクリプトが実行されてしまうような Web サイトの弱点をついた攻撃をクロスサイトスクリプト攻撃などと呼びます。今回の場合はある意味意図していましたが。
テキストボックス同様、ラベルコントロールの場合でもスクリプトとして実行せずに、文字列としてラベルコントロールに表示する方法としては、Server.HtmlEncode メソッドなどで HTML エンコードを行う必要があります。
VB.NET
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click ' 文字列としてテキストボックスに表示される Me.TextBox11.Text = "<script>alert('string');</script>" '' スクリプトが実行されてしまう 'Me.Label1.Text = "<script>alert('string');</script>" '文字列としてラベルコントロールに表示される Me.Label1.Text = Server.HtmlEncode("<script>alert('string');</script>") End Sub
なぜテキストボックスの場合はスクリプトが実行されずに文字列としてそのまま表示されたか疑問が残ります。ASP.NET が返してきたレスポンスを確認すると、テキストボックスとラベルではテキストが HTML に展開される方法が異なっていました。以下が、ラベルとテキストボックスにスクリプトを文字列として設定した場合にブラウザに返された HTML ソースです。
<!-- テキストボックスの場合 --> <input name="TextBox1" type="text" value="<script>alert('string');</script>" id="TextBox1" /> <!-- ラベルの場合 --> <span id="Label1"><script>alert('string');</script></span>
テキストボックスの場合は ” < ” はエンコードされ ” & l t ; ” に置き換わりブラウザではスクリプトとして認識されないようです。一方、ラベルの場合はそのままブラウザに 返されていました。
参考
- How To: ASP.NET でインジェクション攻撃から保護する方法(ステップ 1 – ASP.NET の検証の要求の使用)
- How To: ASP.NET でクロスサイト スクリプトを防止する方法