WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

ViewStateUserKey

by WebSurfer 2011年8月19日 20:34

MSDN ライブラリの ASP.NET の組み込み機能を活用し、Web 攻撃を回避する で、ワンクリック攻撃を防ぐために、Page.ViewStateUserKey プロパティにセッション ID を設定することを推奨しています。

その場合、セッションが timeout(デフォルトで 20 分)すると ViewState の検証結果はどうなるでしょうか?

EnableViewStateMac が有効に設定してある場合(デフォルトで有効になっています)例外がスローされると思っていましたが、そうではなかったです。

timeout するとサーバーに保存されていたセッションデータは破棄されますが、セッション ID は書き換えられず、同じ ID が使用され続けます。即ち、Session["xxxxx"] に保存したデータは破棄されても、ブラウザとサーバ間のセッションは維持されるということのようです。

という訳で、ViewStateUserKey をセッション ID に設定してセッションが timeout しても、ViewState の検証結果は有効になります。

ちなみに、セッション ID が再発行されるのは、regenerateExpiredSessionId が有効で、かつ、cookieless モードが ture の場合のみだそうです。

知ってました? 自分は知らなかったです。(笑)

参考に、検証に使ったコードをアップしておきます。sessionState 要素の timeout 属性を短く設定して検証してみました。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

  // timeout するとサーバーのメモリにあるデータは破棄されるが、
  // SessionID は書き換えらえず、同じ ID が使用され続ける。
  // 既定では、セッション ID は regenerateExpiredSessionId が
  // 有効な場合に cookieless モードに対してのみ再発行される。
  // したがって、timeout しても ViewState は有効。
  protected void Page_Init(object sender, EventArgs e)
  {
    ViewStateUserKey = Session.SessionID;
  }

  protected void Page_Load(object sender, EventArgs e)
  {
    if (!Page.IsPostBack)
    {
      Session["message"] = 
        "この文字列はセッションから取得しました。";
    }
    else
    {
      object obj = Session["message"];
      if (obj != null)
      {
        Label1.Text = (string)obj;
      }
      else
      {
        Label1.Text = "セッションが null です。";
      }
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:Button ID="Button1" runat="server" Text="Button" />
    <asp:Label ID="Label1" runat="server"></asp:Label>
  </div>
  </form>
</body>
</html>

-------- 2012/2/6 追記 --------

SessionState 情報を格納しない場合(Session["Data"] = xxxx; というようなコードが存在しない場合)、サーバーは SessionState 情報用のストレージを割り当てません。また、セッション Cookie も発行しません。(2014/7/26 追記:Global.asax に Session_Start ハンドラを追加すると話が違ってきます。詳しくは、Session_Start ハンドラの影響 を参照ください)

SessionID は SessionStateModule が生成しますが、Cookie が送られてこなければ SessionStateModule が生成する SessionID の値はリクエストのたび異なります。

なので、ViewStateUserKey = Session.SessionID; とすることにより、サーバーエラーになります。エラーメッセージは以下の通りです。

"System.Web.HttpException: viewstate MAC の検証フィールドです。このアプリケーションが Web Farm またはクラスタによってホストされている場合、<machineKey> 構成が同一の validationKey および検証アルゴリズムを指定していることを確認してください。AutoGenerate をクラスタで使用することはできません。"

Tags:

Validation

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar