.NETエンタープライズ
Webアプリケーション開発技術大全

Webアプリケーションの状態管理

マイクロソフト コンサルティング本部 赤間 信幸
2004/05/20
Page1 Page2 Page3 Page4

2.5 ViewStateのセキュリティ

 ViewStateとして格納されたデータと、Webコントロールから出力されたViewStateデータは、デフォルトではシリアライズ処理とBase64エンコード処理をした上でクライアントに送出される。鍵付きハッシュが付与されているために改ざんはできないが、以下の2つを行うことは可能である※9

※9 一般的に、ネットワーク系のセキュリティ上のリスクは「盗聴」「偽造・改ざん」「なりすまし」の3つに大別される。ViewStateにおける鍵つきハッシュは主に「偽造・改ざん」に対する対策として有効なものである。

  • ViewState内に含まれるデータの解読
  • 再送攻撃(replay attack、詳細は後述)

 これについて以下に説明する。

 まず、クライアントにHidden INPUT隠しタグを使って送出される__VIEWSTATEデータは、デフォルトでは暗号化されていないため、解読が可能である。一般にもこうした解読ツールは出回っており、例えばViewState Decoderのようなツール※10を利用すると簡単に解読ができてしまう。『解読されても特に問題がない』ようなデータのみをViewStateに入れるのが基本的な設計セオリーであるが、何らかの理由によりどうしても解読を防ぎたい場合には、ViewStateデータを暗号化する必要がある。

※10 Fritz Onion氏のWebページ(http://staff.develop.com/onion/)から入手することが可能。

 ViewStateデータの暗号化の有無は、各Webページに設定されたenableViewStateMACプロパティの設定※11と、web.config(またはmachine.config)ファイルのmachineKeyセクションのvalidation属性の設定の組み合わせによって決まる。具体的には表3の通りとなる。

※11 一括指定したい場合には、web.configまたはmachine.configファイル中にあるpagesセクションのenableViewStateMac属性を利用する。
 
enableViewStateMAC validation指定 改ざん検知 暗号化
無指定またはtrue SHA1 ○ (SHA1) ×
3DES ○ (SHA1) ○ (3DES)
false SHA1 × ×
3DES × ×
表3 ViewStateデータの暗号化の有無
 
図8 enableViewStateMACプロパティのデフォルト設定は実際にはtrue

 デフォルトではvalidation属性がSHA1、enableViewStateMACプロパティは無指定※12となっている(図8)。このため、改ざん検知(鍵付きハッシュの付与)は行われるが、暗号化は行われない。

※12 無指定の場合、画面上ではFalseと表示されているが、実際にはTrueとして動作する(Visual Studio .NET2002、2003の両方に共通するバグである)。

 ViewStateの暗号化が必要な場合には、web.config(またはmachine.config)ファイルのmachineKeyセクションのvalidation属性にて、3DESを指定する。これにより、ViewStateにはSHA1の鍵付きハッシュが付与されると同時に、3DESの暗号化が施されるようになり、クライアント側での解読ができなくなる(実際にViewState Decoderなどのツールを利用して、動作を確認してみるとよいだろう)。

 なお、ViewStateの暗号化に関しては、性能への影響もあるため、むやみに利用するべきではない。SessionとViewStateの基本的な使い分けで解説したように、解読されては困るようなセキュアな情報については、サーバ側にSessionデータとして保存することが望ましい

 また、暗号化だけではセキュリティ上のリスクを完全になくすことはできない。システムの作り方によっては、1クリック攻撃と呼ばれる再送攻撃を受ける場合がある。

 1クリック攻撃とは、自分向けに作成されたポストバック用データを他人に使わせることによって、システムに不正動作を起こさせるテクニックである。

 ASP.NETのViewStateハッシュ値算出ロジックおよび暗号化処理は、デフォルトではユーザが誰であるのかを識別しない。このため、あるユーザ向けに送出されたViewStateデータを別のユーザがサーバに再送しても、サーバ側ではそれが不正送信されたものであることに気付けず、ViewStateデータを復元してしまう(図9)。

図9 1クリック攻撃の流れ

 1クリック攻撃を利用した攻撃としては、以下のような例が挙げられる。例えば悪意のある攻撃者が「100万円の物品購入を確定する直前のページ」を作成し、そこからViewStateを抽出して他のユーザに渡してボタンをクリックさせる※13。このようにすると、他のユーザに、意図してしない物品購入をさせることが可能になる。

※13 実際には直接ページを渡してクリックさせるのではなく、CSS(クロスサイトスクリプティング)と同様な手法、例えばHTMLメールの利用や不正サイトへの誘導といった方法が利用される。

 1クリック攻撃は、ViewStateデータ(ポストバックデータ)が、クライアント(あるいはセッション)と紐付けされていないことを利用した攻撃である。このような攻撃を防止するためには、ViewStateデータを、クライアントの認証情報やセッション情報と紐付けしておけばよい(図10)。具体的にはリスト7のようなチェックロジックを組み込む※14

※14 .NET Framework 1.1を利用している場合には、Pageクラスに新しく追加されたViewStateUserKeyプロパティを利用してもよい。
 
図10 1クリック攻撃が事実上行えないケース

C#の場合

private void Page_Load(object sender, System.EventArgs e)
{
  if (IsPostBack == false)
  {
    ViewState["ViewStateUserKey"] = User.Identity.Name;
    // またはSessionキーを利用してもよい。
    // ViewState["ViewStateUserKey"] = Session.SessionID;
  }
  else
  {
    if ((string)ViewState["ViewStateUserKey"] != User.Identity.Name)
    {
      throw new ApplicationException("不正な再送攻撃が行われた可能性があります。");
    }
  }
}
VB.NETの場合

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  If IsPostBack = False Then
    ViewState("ViewStateUserKey") = User.Identity.Name
    ' またはSessionキーを利用してもよい。
    ' ViewState("ViewStateUserKey") = Session.SessionID;
  Else
    If CType(ViewState("ViewStateUserKey"), String) <> User.Identity.Name Then
      Throw New ApplicationException("不正な再送攻撃が行われた可能性があります。")
    End If
  End If
End Sub
リスト7 1クリック攻撃に対処するコード例

 このような1クリック攻撃に対する対策は、すべてのページに必要なわけではない。特に参照系のページでは、再送攻撃を受けても業務的には無害であることが多い。また更新系のページでも、当該ユーザに対応するサーバ側のSessionデータがなければ、うまく処理が行われないことがほとんどだろう。

 しかし、サーバ側のSessionデータなどを一切利用せず、単一のポストバック処理のみでサーバ側の処理が確定されるようなプログラムでは、1クリック攻撃に対する対策が必要である。

 ViewStateに関する注意事項は以上である。引き続き、Sessionオブジェクトの利用方法とその注意点について解説する。End of Article

.NETエンタープライズWebアプリケーション開発技術大全
Vol.3 ASP.NET 応用編
定価 3,990円(税込み)

赤間 信幸(マイクロソフト株式会社コンサルティング本部) 著
B5変型判/380p
ISBN 4-89100-429-0
日経BPソフトプレス発行


日経BPソフトプレスの書籍紹介ページへ
マイクロソフトプレスの書籍紹介ページへ
 
 

 INDEX
  .NETエンタープライズWebアプリケーション開発技術大全
  Webアプリケーションの状態管理
    1.状態管理の手法
    2.ViewStateとSessionの使い分け/データサイズの最適化
    3.Webファームを利用する場合の暗号化鍵の設定
  4.ViewStateのセキュリティ
 
インデックス・ページヘ  「.NETエンタープライズWebアプリケーション開発技術大全」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間