我正在使用自动生成的代码来防止使用asp.net Web应用程序进行跨站点伪造攻击 - 即:
protected const string AntiXsrfTokenKey = "__AntiXsrfToken";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
var requestCookie = Request.Cookies[AntiXsrfTokenKey];
Guid requestCookieGuidValue;
if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
{
_antiXsrfTokenValue = requestCookie.Value;
Page.ViewStateUserKey = _antiXsrfTokenValue;
当使用Ajax / Webmethod请求时,我还希望在更改数据库之前验证请求,方法是回发_VIEWSTATE隐藏输入的值。
然而,当我尝试
时internal static void Validate(string encodedViewstate)
{
var request = HttpContext.Current.Request;
var requestCookie = request.Cookies[AntiXsrfTokenKey];
var antiXsrfTokenValue = requestCookie.Value;
var los = new System.Web.UI.LosFormatter(true, antiXsrfTokenValue);
var xsrfData = los.Deserialize(encodedViewstate);
los.Deserialize方法失败:
Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm
即,单独的UserKey不是编码的视图状态字符串的正确密钥。
在设置ViewStateUserKey属性(即MAC和UserKey的某种组合)之后,任何人都可以帮助解决如何对视图状态进行反序列化的问题。感谢您的想法/专长。
答案 0 :(得分:1)
您需要使用Page本身使用的相同PageStatePersister实例。否则此检查将无法可靠地运行。例如,在Page的代码隐藏中考虑这个实例方法:
private void CheckCsrfToken() {
var persister = this.PageStatePersister;
persister.Load();
if (persister.ViewState == null) {
throw new Exception("Validation failed.");
}
}
只要设置了Page.ViewStateUserKey,返回的persister实例的修饰符也会相应设置。