QA@IT

ASP.NETのエラーページ表示時のランタイムエラーについて

10178 PV

ASP.NET(3.5)のWebサイトに対して、脆弱性診断ツール(OWASP ZAP)にて診断した所、
「アプリケーションエラーの開示」(500エラー)のアラートが出ました。

内容としては、以下のURL(カスタムエラーページ)に対してPOSTをした場合
HTTP 500エラー(Internal Server Error)が出るというものでした。

https://hogehoge.jp/error.aspx?aspxerrorpath=hoge.aspx

環境、設定等は以下の通り。

[環境]
IIS: 7.0 (Windows Server2008)
ASP.NET : 3.5

[web.configのカスタムエラーページの設定]

<customErrors defaultRedirect="error.aspx" mode="RemoteOnly"></customErrors>

[POST内容]
URL : https://hogehoge.jp/error.aspx?aspxerrorpath=hoge.aspx
Body : VIEWSTATE=~&VIEWSTATEGENERATOR=~ (__VIEWSTATE=[適当な値]でも発生)

[エラー内容]
「Viewstate 検証に失敗しました。 原因: 指定された viewstate で整合性チェックに失敗しました。」

恐らくエラーページを表示しようとしてエラーとなっている為、ランタイムエラーのページが表示されている?のかと思います。

この対処として、以下の通りGlobal.asaxのApplication_BeginRequestにて、
URLの"?aspxerrorpath=hoge.aspx"のクエリ部分を削除すると発生しなくなりました。

Protected Sub Application_BeginRequest(ByVal sender As Object, ByVal e As System.EventArgs)

    If Not IsNothing(Request.QueryString("aspxerrorpath")) Then
        Dim requestPath As String = Request.ServerVariables("PATH_INFO")
        Response.Redirect(requestPath)
    End If

End Sub

疑問点は、これでなぜランタイムエラーが発生しなくなるのか分かりません。
(リダイレクトさせることで送られた無効なViewStateを読まないから?)

あとはここまでする必要があるのか謎です。。。
(ランタイムエラーページは内部情報が分かるような内容は含まれていませんし、
aspxerrorpathクエリを削除してしまうと、エラー元のページ名が分からなくなる。)

どなたか分かる方ご教授頂けると助かります。

回答

脆弱性診断ツール(OWASP ZAP) というのが何をしているか分からないので想像が入ってますが・・・

内容としては、以下のURL(カスタムエラーページ)に対してPOSTをした場合 HTTP 500エラー(Internal Server Error)が出るというものでした。

これは POST 要求した際に送信した ViewState が不正のためサーバーエラーとなったということだと思います。

ViewState の検証については、ご存知かもしれませんが、以下の記事の「ビューステートのセキュリティ保護」のセクションを見てください。

ASP.NET ビューステートの概要
https://msdn.microsoft.com/ja-jp/library/bb386448.aspx

疑問点は、これでなぜランタイムエラーが発生しなくなるのか分かりません。(リダイレクトさせることで送られた無効なViewStateを読まないから?)

これも想像が入ってますが、

ViewState の検証がかかる前に Response.Redirect(requestPath) で処理が中断され直ちに HTTP 302 応答と応答ヘッダの Location に requestPath を設定してブラウザに返す ⇒ ブラウザは Location の requestPath を GET 要求に行く ⇒ GET 要求なので ViewState の問題はない

・・・ということだと思います。

あとはここまでする必要があるのか謎です。。。(ランタイムエラーページは内部情報が分かるような内容は含まれていませんし、aspxerrorpathクエリを削除してしまうと、エラー元のページ名が分からなくなる。)

問題はクエリ文字列 aspxerrorpath ではなく、脆弱性診断ツール(OWASP ZAP) が不正な ViewState を POST するということにありそうです。

不正な ViewState を POST するということは想像が入ってますが、結果からみると間違いなさそうです。その想像が正しければ今回の問題は気にしなくていいと思われます。

想像が正しいかどうか、ViewState の検証を無効にしてみる等で確認してはいかがですか?

【追記】

以下は質問者さんが回答欄に書いたことへのレスです。

(ただ一般的には500エラーは脆弱性扱いとなっていますが。。。)

「HTTP 500 エラー」=「脆弱性」では決してないです。

不正な ViewState を送られたらサーバーエラーとして処置を中断するのは「偽造・改ざん」対策です。それ自体は決して脆弱性ではなく、逆にセキュリティ対策です。詳しくは以下の記事を見てください。

2.5 ViewStateのセキュリティ
http://www.atmarkit.co.jp/fdotnet/entwebapp/entwebapp03/entwebapp03_04.html

問題は、もしクライアントに HTTP 500 エラーが返ってくるとすると、クライアント側でサーバーエラーになったことが分かるということです。それは脆弱性と言えるかもしれません。

でも、そこはカスタムエラーページを実装するなどして HTTP 500 エラーという情報は返さないようにすれば良いのではないですか? 具体的には以下の記事を見てください。それができれば脆弱性にはならないです。

ASP.NETでのWebアプリケーションのエラー処理
https://codezine.jp/article/detail/81

htmlソースを見る限り、ViewStateを無効にしても、レスポンスには必ず"__VIEWSTATE"が含まれてしまう様です。

ASP.NET 2.0 以降では、ViewState とは別に、ControlState と呼ばれる別個のオブジェクトにサーバーコントロールが機能するために必要な状態情報が格納されます。開発者が ViewState を無効にしても ControlState は影響を受けません。たぶん、そのせいではないかと思います。

ただ、enableViewStateMAC を false にすると、【追記】の一番上に紹介した記事に書いてあるように「改ざん検知」は無効になるはずなのですが・・・

編集 履歴 (2)

SurferOnWww様

再度回答ありがとうございます。大変助かります。
 

不正な ViewState を送られたらサーバーエラーとして処置を中断するのは「偽造・改ざん」対策です。それ自体は決して脆弱性ではなく、
問題は、もしクライアントに HTTP 500 エラーが返ってくるとすると、クライアント側でサーバーエラーになったことが分かるということです。それは脆弱性と言えるかもしれません。

はい。その辺は理解しています。
 

でも、そこはカスタムエラーページを実装するなどして HTTP 500 エラーという情報は返さないようにすれば良いのではないですか? 具体的には以下の記事を見てください。それができれば脆弱性にはならないです。

はい。今回のケースで、カスタムエラーページにてエラーが出た場合は、ランタイムエラー(500エラー)となることが分かりました。
最初の対応としては、Global.asaxでリダイレクトさせて不正なViewStateがない状態にしましたが、その他の例外もあり得るので、一番良いのはカスタムエラーページ内でも例外を捕捉し、500エラーを出さない様にする様にした方が良いと思いました。
 

ASP.NET 2.0 以降では、ViewState とは別に、ControlState と呼ばれる別個のオブジェクトにサーバーコントロールが機能するために必要な状態情報が格納されます。開発者が ViewState を無効にしても ControlState は影響を受けません。たぶん、そのせいではないかと思います。

なるほどですね。この辺は中々調べても出てこなかったので勉強になります。
 

ただ、enableViewStateMAC を false にすると、【追記】の一番上に紹介した記事に書いてあるように「改ざん検知」は無効になるはずなのですが・・・

何度か試しましたが、やはりどうしても不正なViewStateとして検知されました。
ControlState だけは enableViewStateMAC の影響を受けないのかもしれないですね。

編集 履歴 (0)
  • ここは、回答者さんは回答欄には書かないのが流儀のようです。なので、回答欄に何度も書かれるとスレッドの流れ分からなくなってしまう恐れがあります。ご配慮ください。 -
  • ですよね。すいません。
    今回新しくなって始めて利用しましたが、回答に対しての返信がしづらいですね。
    (追記していくのも分かりづらくなっていくように思うし。。。)
    兎にも角にもSurferOnWww様ありがとうございました。とても勉強になりました。
    -

SurferOnWww様

回答ありがとうございます。

ViewState の検証がかかる前に Response.Redirect(requestPath) で処理が中断され直ちに HTTP 302 応答と応答ヘッダの Location に requestPath を設定してブラウザに返す ⇒ ブラウザは Location の requestPath を GET 要求に行く ⇒ GET 要求なので ViewState の問題はない

・・・ということだと思います。

なるほどですね。すっきりしました。
 

問題はクエリ文字列 aspxerrorpath ではなく、脆弱性診断ツール(OWASP ZAP) が不正な ViewState を POST するということにありそうです。

あえて不正なViewStateでPostすることでエラーページを表示させて内部情報を表示させるのが目的かと思います。
ただ今回は表示されるランタイムエラーのページには、内部情報は含まれていないので良しとしようと思います。
(ただ一般的には500エラーは脆弱性扱いとなっていますが。。。)
 

想像が正しいかどうか、ViewState の検証を無効にしてみる等で確認してはいかがですか?

web.configにて、以下の様にViewStateのMAC検証しない様にし、更にViewState自体を無効としてみましたが、同様の500エラー(不正なViewState)が発生してしまいました。
htmlソースを見る限り、ViewStateを無効にしても、レスポンスには必ず"__VIEWSTATE"が含まれてしまう様です。

<pages enableViewState="false" enableViewStateMac="false" viewStateEncryptionMode="Never" />
編集 履歴 (1)
  • 上へのレスはコメント欄には書ききれないので、回答欄に追記します。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。