14

これまでの調査で、クロス サイト スクリプティングを回避するために GET 要求操作で AllowUnsafeUpdates を設定するのは賢明ではないことがわかりました。しかし、これを許可する必要がある場合、暴露を軽減するために状況を処理する適切な方法は何ですか?

これは、GET 要求で Web またはサイトの更新を絶対に許可する必要がある場合の、信頼できるパターンに関する私の最善の最初の推測です。

ベストプラクティス?

protected override void OnLoad(System.EventArgs e)
{
    if(Request.HttpMethod == "POST")
    {
        SPUtility.ValidateFormDigest();
        // will automatically set AllowSafeUpdates to true
    }

    // If not a POST then AllowUnsafeUpdates should be used only
    // at the point of update and reset immediately after finished

    // NOTE: Is this true? How is cross-site scripting used on GET
    // and what mitigates the vulnerability?
}

// Point of item update

    using(SPSite site = new SPSite(SPContext.Current.Site.Url, SPContext.Current.Site.SystemAccount.UserToken))
    {
        using (SPWeb web = site.RootWeb)
        {
            bool allowUpdates = web.AllowUnsafeUpdates; //store original value
            web.AllowUnsafeUpdates = true;

            //... Do something and call Update() ...

            web.AllowUnsafeUpdates = allowUpdates; //restore original value

        }
    }

最良のパターンに関するフィードバックをお待ちしております。

4

6 に答える 6

7

何かを変更する操作を実行している場合、ユーザーにリンクをクリックするよう説得できる人なら誰でもその操作を実行できます。たとえば、ユーザーが管理者をサイトに追加できるようにするページへの GET 要求があり、ユーザーが Response.Redirect(" http://yourserver/_layouts/ admin.aspx?operation=addAdministrator&username=attackerNameHere ")。

通常、POST はこれに対して十分な保護を提供しませんが (<form method="post" action="http://yourserver/_layouts/admin.aspx"> を持つことを止めるものは何もありません)、SharePoint にはフォームの概念があります。ダイジェストには、ポストバックを生成している以前のリクエストに関する情報 (ユーザーの名前を含む) が含まれています。これにより、この種の攻撃のフットプリントが大幅に減少します。

GET で AllowUnsafeUpdates がセキュリティ上の問題にならないのは、ユーザーからの入力を取得していない場合のみです。たとえば、リストへのアクセスもログに記録する Web パーツがある場合、セキュリティの脆弱性は公開されません。

編集: AllowUnsafeUpdates を使用する場合は、以前の値にリセットする必要はありません。永続化されません。これは、GET (またはその他の場合) からの更新を実行する前に、SPWeb オブジェクトに設定する必要があるものです。

于 2008-12-18T22:59:18.187 に答える
5

トレントのデリゲートを少し変更して、更新する Web を受け入れるようにします。

public static void DoUnsafeUpdate(this SPWeb web, Action<SPWeb> action)
{
    try
    {
        web.AllowUnsafeUpdates = true;
        action(web);
    }
    finally
    {
        web.AllowUnsafeUpdates = false;
    }
}

次に、フォーム ダイジェストの検証をカプセル化するために HttpContext を拡張し、ここで説明する手法を使用して昇格するオプションを使用します。

public static void DoUnsafeUpdate(this HttpContext context, Action<SPWeb> action, bool elevated)
{
    SPWeb web = SPControl.GetContextWeb(context);
    if (!context.Request.HttpMethod.Equals("POST", StringComparison.Ordinal)
        || web.ValidateFormDigest())
        throw new SPException("Error validating postback digest");

    if (elevated)
        web.RunAsSystem(w => w.DoUnsafeUpdate(action));
    else
        web.DoUnsafeUpdate(action);
}

使用法:

protected override void OnLoad(System.EventArgs e)
{
    Context.DoUnsafeUpdate(web =>
    {
        // Update elevated web
    }, true);
}
于 2009-01-12T18:40:44.643 に答える
4

実装するもう 1 つのクリーンな方法は、拡張メソッドと匿名デリゲートを組み合わせて使用​​することです。

public static void DoUnsafeUpdate(this SPWeb web, Action action)
{
    bool allowUnsafeUpdates = web.AllowUnsafeUpdates;
    web.AllowUnsafeUpdates = true;
    action();
    web.AllowUnsafeUpdates = allowUnsafeUpdates;
}

上記の拡張メソッドを使用すると、次のように「安全でない更新」アクションを実行できます。

var web = SPContext.Current.Web;
web.DoUnsafeUpdate(delegate()
{
    // Put your "unsafe update" code here
});
于 2009-01-12T17:01:03.427 に答える
2

AllowUnsafeUpdates については、次のプロセスに従います。

if( HttpContext.Current is null )
{
  Do nothing, no need to set AllowUnsafeUpdates to true nor
  to call ValidateFormDigest() because update will be carried out
}
else // HttpContext.Current is NOT null
{
  if( SPContext.Current is null )
  {
    Need to set AllowUnsafeUpdates to true
  }
  else // SPContext.Current is NOT null
  {
    Call ValidateFormDigest()
  }
}
于 2009-06-27T05:33:23.103 に答える
1

安全でない更新を許可するという以前の値を覚えておく価値があるかどうかはわかりません。

ネストされた呼び出しが発生しないように、可能な限り最小限のコードで呼び出しをラップしたいと思います。

その後、後で false に変更できます。

于 2008-10-20T22:35:21.940 に答える