我使用Visual Studio 2013创建了一个ASP.Net Web窗体应用程序,我使用的是.NET Framework 4.5。我想确保我的网站是安全的跨站点请求伪造(CSRF),我发现很多文章谈论如何在MVC应用程序上实现此功能,但很少谈论Web窗体。在this StackOverflow question上有一条评论指出
“这是一个老问题,但是最新的Visual Studio 2012 ASP.NET Web表单的模板包括烘焙到主服务器中的反CSRF代码 页。如果您没有模板,请输入以下代码 生成:...“
我的母版页不包含该答案中提到的代码。它真的包含在新的应用程序中吗?如果没有,添加它的最佳方法是什么?
答案 0 :(得分:27)
您可以尝试以下方法。在Web表单中添加:
Unmarshalling Error: unexpected element (uri:"http://www.namedomain.com", local:"loginRequest"). Expected elements are <{https://www.namedomain.com}loginRequest>
这将添加隐藏字段和cookie。因此,如果您填写一些表单数据并将其发回服务器,则需要进行简单的检查:
<%= System.Web.Helpers.AntiForgery.GetHtml() %>
如果反XSFR检查失败, protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
AntiForgery.Validate();
}
会抛出异常。
答案 1 :(得分:19)
ViewStateUserKey&amp;双提交Cookie
从Visual Studio 2012开始,Microsoft为新的Web表单应用程序项目添加了内置的CSRF保护。要使用此代码,请在解决方案中添加新的ASP .NET Web窗体应用程序,并查看页面后面的Site.Master代码。此解决方案将对从Site.Master页面继承的所有内容页面应用CSRF保护。
此解决方案必须满足以下要求:
所有进行数据修改的网络表单都必须使用Site.Master页面。 所有进行数据修改的请求都必须使用ViewState。 该网站必须没有所有跨站点脚本(XSS)漏洞。有关详细信息,请参阅如何使用Microsoft .Net Web Protection Library修复跨站点脚本(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.");
}
}
}
}
答案 2 :(得分:9)
当您创建新的“Web表单应用程序”时,在VS 2013中,site.master.cs将自动在类的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.");
}
}
}
答案 3 :(得分:-5)
您可以使用下面的代码,它将检查来自
的请求if ((context.Request.UrlReferrer == null || context.Request.Url.Host != context.Request.UrlReferrer.Host))
{
context.Response.Redirect("~/error.aspx", false);
}
它对我很有用!!!