防止 asp.net 网络表单中的跨站点请求伪造 (csrf) 攻击
preventing cross-site request forgery (csrf) attacks in asp.net web forms
我使用 Visual Studio 2013 创建了一个 ASP.Net Web 表单应用程序,并且我使用的是 .NET Framework 4.5。我想确保我的网站免受跨站请求伪造 (CSRF) 的侵害,我发现很多文章都在谈论如何在 MVC 应用程序上实现此功能,但很少有人谈论 Web 窗体。在 this Whosebug question 上,一条评论指出
"This is an old question, but the latest Visual Studio 2012 ASP.NET
template for web forms includes anti-CSRF code baked into the master
page. If you don't have the templates, here's the code it
generates:..."
我的母版页不包含该答案中提到的代码。它真的包含在新的应用程序中吗?如果没有,最好的添加方式是什么?
当您在 VS 2013 中创建新的 'Web Form Application' 项目时,site.master.cs 将自动在 [=19= 的 Page_Init
部分包含 XSRF/CSRF 代码].如果您仍然没有得到生成的代码,您可以手动 Copy
+ Paste
代码。如果您使用的是 C#,请使用以下内容:-
private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
// The code below helps to protect against XSRF attacks
var requestCookie = Request.Cookies[AntiXsrfTokenKey];
Guid requestCookieGuidValue;
if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
{
// Use the Anti-XSRF token from the cookie
_antiXsrfTokenValue = requestCookie.Value;
Page.ViewStateUserKey = _antiXsrfTokenValue;
}
else
{
// Generate a new Anti-XSRF token and save to the cookie
_antiXsrfTokenValue = Guid.NewGuid().ToString("N");
Page.ViewStateUserKey = _antiXsrfTokenValue;
var responseCookie = new HttpCookie(AntiXsrfTokenKey)
{
HttpOnly = true,
Value = _antiXsrfTokenValue
};
if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
{
responseCookie.Secure = true;
}
Response.Cookies.Set(responseCookie);
}
Page.PreLoad += master_Page_PreLoad;
}
protected void master_Page_PreLoad(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Set Anti-XSRF token
ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty;
}
else
{
// Validate the Anti-XSRF token
if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
|| (string)ViewState[AntiXsrfUserNameKey] != (Context.User.Identity.Name ?? String.Empty))
{
throw new InvalidOperationException("Validation of Anti-XSRF token failed.");
}
}
}
ViewStateUserKey & 双重提交 Cookie
从 Visual Studio 2012 年开始,Microsoft 为新的 Web 表单应用程序项目添加了内置的 CSRF 保护。要使用此代码,请将新的 ASP .NET Web 窗体应用程序添加到您的解决方案并查看 Site.Master 代码隐藏页面。此解决方案将对从 Site.Master 页面继承的所有内容页面应用 CSRF 保护。
要使该解决方案起作用,必须满足以下要求:
所有进行数据修改的网络表单都必须使用Site.Master页面。
所有进行数据修改的请求都必须使用 ViewState。
该网站必须没有所有跨站点脚本 (XSS) 漏洞。有关详细信息,请参阅如何使用 Microsoft .Net Web 保护库修复跨站点脚本 (XSS)。
public partial class SiteMaster : MasterPage
{
private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
//First, check for the existence of the Anti-XSS cookie
var requestCookie = Request.Cookies[AntiXsrfTokenKey];
Guid requestCookieGuidValue;
//If the CSRF cookie is found, parse the token from the cookie.
//Then, set the global page variable and view state user
//key. The global variable will be used to validate that it matches
//in the view state form field in the Page.PreLoad method.
if (requestCookie != null
&& Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
{
//Set the global token variable so the cookie value can be
//validated against the value in the view state form field in
//the Page.PreLoad method.
_antiXsrfTokenValue = requestCookie.Value;
//Set the view state user key, which will be validated by the
//framework during each request
Page.ViewStateUserKey = _antiXsrfTokenValue;
}
//If the CSRF cookie is not found, then this is a new session.
else
{
//Generate a new Anti-XSRF token
_antiXsrfTokenValue = Guid.NewGuid().ToString("N");
//Set the view state user key, which will be validated by the
//framework during each request
Page.ViewStateUserKey = _antiXsrfTokenValue;
//Create the non-persistent CSRF cookie
var responseCookie = new HttpCookie(AntiXsrfTokenKey)
{
//Set the HttpOnly property to prevent the cookie from
//being accessed by client side script
HttpOnly = true,
//Add the Anti-XSRF token to the cookie value
Value = _antiXsrfTokenValue
};
//If we are using SSL, the cookie should be set to secure to
//prevent it from being sent over HTTP connections
if (FormsAuthentication.RequireSSL &&
Request.IsSecureConnection)
{
responseCookie.Secure = true;
}
//Add the CSRF cookie to the response
Response.Cookies.Set(responseCookie);
}
Page.PreLoad += master_Page_PreLoad;
}
protected void master_Page_PreLoad(object sender, EventArgs e)
{
//During the initial page load, add the Anti-XSRF token and user
//name to the ViewState
if (!IsPostBack)
{
//Set Anti-XSRF token
ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
//If a user name is assigned, set the user name
ViewState[AntiXsrfUserNameKey] =
Context.User.Identity.Name ?? String.Empty;
}
//During all subsequent post backs to the page, the token value from
//the cookie should be validated against the token in the view state
//form field. Additionally user name should be compared to the
//authenticated users name
else
{
//Validate the Anti-XSRF token
if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
|| (string)ViewState[AntiXsrfUserNameKey] !=
(Context.User.Identity.Name ?? String.Empty))
{
throw new InvalidOperationException("Validation of " +
"Anti-XSRF token failed.");
}
}
}
}
您可以尝试以下方法。在 Web 表单中添加:
<%= System.Web.Helpers.AntiForgery.GetHtml() %>
这将添加一个隐藏字段和一个 cookie。因此,如果您填写一些表单数据并将其 post 返回到服务器,您需要进行简单的检查:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
AntiForgery.Validate(); // throws an exception if anti XSFR check fails.
}
AntiForgery.Validate();
如果反 XSFR 检查失败则抛出异常。
您可以使用下面的代码,它会检查请求的来源
if ((context.Request.UrlReferrer == null || context.Request.Url.Host != context.Request.UrlReferrer.Host))
{
context.Response.Redirect("~/error.aspx", false);
}
对我来说效果很好!!!
我使用 Visual Studio 2013 创建了一个 ASP.Net Web 表单应用程序,并且我使用的是 .NET Framework 4.5。我想确保我的网站免受跨站请求伪造 (CSRF) 的侵害,我发现很多文章都在谈论如何在 MVC 应用程序上实现此功能,但很少有人谈论 Web 窗体。在 this Whosebug question 上,一条评论指出
"This is an old question, but the latest Visual Studio 2012 ASP.NET template for web forms includes anti-CSRF code baked into the master page. If you don't have the templates, here's the code it generates:..."
我的母版页不包含该答案中提到的代码。它真的包含在新的应用程序中吗?如果没有,最好的添加方式是什么?
当您在 VS 2013 中创建新的 'Web Form Application' 项目时,site.master.cs 将自动在 [=19= 的 Page_Init
部分包含 XSRF/CSRF 代码].如果您仍然没有得到生成的代码,您可以手动 Copy
+ Paste
代码。如果您使用的是 C#,请使用以下内容:-
private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
// The code below helps to protect against XSRF attacks
var requestCookie = Request.Cookies[AntiXsrfTokenKey];
Guid requestCookieGuidValue;
if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
{
// Use the Anti-XSRF token from the cookie
_antiXsrfTokenValue = requestCookie.Value;
Page.ViewStateUserKey = _antiXsrfTokenValue;
}
else
{
// Generate a new Anti-XSRF token and save to the cookie
_antiXsrfTokenValue = Guid.NewGuid().ToString("N");
Page.ViewStateUserKey = _antiXsrfTokenValue;
var responseCookie = new HttpCookie(AntiXsrfTokenKey)
{
HttpOnly = true,
Value = _antiXsrfTokenValue
};
if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
{
responseCookie.Secure = true;
}
Response.Cookies.Set(responseCookie);
}
Page.PreLoad += master_Page_PreLoad;
}
protected void master_Page_PreLoad(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Set Anti-XSRF token
ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty;
}
else
{
// Validate the Anti-XSRF token
if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
|| (string)ViewState[AntiXsrfUserNameKey] != (Context.User.Identity.Name ?? String.Empty))
{
throw new InvalidOperationException("Validation of Anti-XSRF token failed.");
}
}
}
ViewStateUserKey & 双重提交 Cookie
从 Visual Studio 2012 年开始,Microsoft 为新的 Web 表单应用程序项目添加了内置的 CSRF 保护。要使用此代码,请将新的 ASP .NET Web 窗体应用程序添加到您的解决方案并查看 Site.Master 代码隐藏页面。此解决方案将对从 Site.Master 页面继承的所有内容页面应用 CSRF 保护。
要使该解决方案起作用,必须满足以下要求:
所有进行数据修改的网络表单都必须使用Site.Master页面。 所有进行数据修改的请求都必须使用 ViewState。 该网站必须没有所有跨站点脚本 (XSS) 漏洞。有关详细信息,请参阅如何使用 Microsoft .Net Web 保护库修复跨站点脚本 (XSS)。
public partial class SiteMaster : MasterPage
{
private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
//First, check for the existence of the Anti-XSS cookie
var requestCookie = Request.Cookies[AntiXsrfTokenKey];
Guid requestCookieGuidValue;
//If the CSRF cookie is found, parse the token from the cookie.
//Then, set the global page variable and view state user
//key. The global variable will be used to validate that it matches
//in the view state form field in the Page.PreLoad method.
if (requestCookie != null
&& Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
{
//Set the global token variable so the cookie value can be
//validated against the value in the view state form field in
//the Page.PreLoad method.
_antiXsrfTokenValue = requestCookie.Value;
//Set the view state user key, which will be validated by the
//framework during each request
Page.ViewStateUserKey = _antiXsrfTokenValue;
}
//If the CSRF cookie is not found, then this is a new session.
else
{
//Generate a new Anti-XSRF token
_antiXsrfTokenValue = Guid.NewGuid().ToString("N");
//Set the view state user key, which will be validated by the
//framework during each request
Page.ViewStateUserKey = _antiXsrfTokenValue;
//Create the non-persistent CSRF cookie
var responseCookie = new HttpCookie(AntiXsrfTokenKey)
{
//Set the HttpOnly property to prevent the cookie from
//being accessed by client side script
HttpOnly = true,
//Add the Anti-XSRF token to the cookie value
Value = _antiXsrfTokenValue
};
//If we are using SSL, the cookie should be set to secure to
//prevent it from being sent over HTTP connections
if (FormsAuthentication.RequireSSL &&
Request.IsSecureConnection)
{
responseCookie.Secure = true;
}
//Add the CSRF cookie to the response
Response.Cookies.Set(responseCookie);
}
Page.PreLoad += master_Page_PreLoad;
}
protected void master_Page_PreLoad(object sender, EventArgs e)
{
//During the initial page load, add the Anti-XSRF token and user
//name to the ViewState
if (!IsPostBack)
{
//Set Anti-XSRF token
ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
//If a user name is assigned, set the user name
ViewState[AntiXsrfUserNameKey] =
Context.User.Identity.Name ?? String.Empty;
}
//During all subsequent post backs to the page, the token value from
//the cookie should be validated against the token in the view state
//form field. Additionally user name should be compared to the
//authenticated users name
else
{
//Validate the Anti-XSRF token
if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
|| (string)ViewState[AntiXsrfUserNameKey] !=
(Context.User.Identity.Name ?? String.Empty))
{
throw new InvalidOperationException("Validation of " +
"Anti-XSRF token failed.");
}
}
}
}
您可以尝试以下方法。在 Web 表单中添加:
<%= System.Web.Helpers.AntiForgery.GetHtml() %>
这将添加一个隐藏字段和一个 cookie。因此,如果您填写一些表单数据并将其 post 返回到服务器,您需要进行简单的检查:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
AntiForgery.Validate(); // throws an exception if anti XSFR check fails.
}
AntiForgery.Validate();
如果反 XSFR 检查失败则抛出异常。
您可以使用下面的代码,它会检查请求的来源
if ((context.Request.UrlReferrer == null || context.Request.Url.Host != context.Request.UrlReferrer.Host))
{
context.Response.Redirect("~/error.aspx", false);
}
对我来说效果很好!!!