我已经做了一些关于使用ValidateAntiForgeryToken
来防止XSRF / CSRF攻击的文章。然而,我所看到的似乎只与MVC有关。
这些是我见过的文章:
ValidateAntiForgeryToken purpose, explanation and example
XSRF/CSRF Prevention in ASP.NET MVC and Web Pages
如何在WebForms应用程序中实现此类或类似的东西?
CSRF攻击并不是MVC应用程序所独有的,webforms也很容易受到攻击。
基本上,CSRF攻击利用站点在用户浏览器中的信任,通过请求或向网站发布信息,通常通过隐藏的表单或恶意网站内的JavaScript XMLHttpRequests,作为用户使用存储在浏览器中的cookie。
为防止此类攻击,您需要一个防伪令牌,即在您的表单中发送的唯一令牌,您需要在信任表单信息之前进行验证。
你可以找到详细的解释here。
要保护您的webforms应用程序免受CSRF攻击(它在我的项目中工作),要在您的母版页中实现它,如下所示:
添加将为您处理CSRF验证的新类:
public class CsrfHandler
{
public static void Validate(Page page, HiddenField forgeryToken)
{
if (!page.IsPostBack)
{
Guid antiforgeryToken = Guid.NewGuid();
page.Session["AntiforgeryToken"] = antiforgeryToken;
forgeryToken.Value = antiforgeryToken.ToString();
}
else
{
Guid stored = (Guid)page.Session["AntiforgeryToken"];
Guid sent = new Guid(forgeryToken.Value);
if (sent != stored)
{
// you can throw an exception, in my case I'm just logging the user out
page.Session.Abandon();
page.Response.Redirect("~/Default.aspx");
}
}
}
}
然后在您的母版页中实现:
MyMasterPage.Master.cs:
protected void Page_Load(object sender, EventArgs e)
{
CsrfHandler.Validate(this.Page, forgeryToken);
...
}
MyMaster.Master:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:HiddenField ID="forgeryToken" runat="server"/>
...
</form>
希望你会发现这很有用。
使用WebForms,最好的办法是利用ViewStateUserKey。
这是怎么做的......
void Page_Init(object sender, EventArgs args)
{
ViewStateUserKey = (string)(Session["SessionID"] = Session.SessionID);
}
将SessionID
保存在会话变量中似乎有点奇怪,但这是必需的,因为它会在空时自动生成新ID。
我发现这篇文章How To Fix Cross-Site Request Forgery (CSRF) using Microsoft .Net ViewStateUserKey and Double Submit Cookie有以下信息代码和说明:
从Visual Studio 2012开始,Microsoft为新的Web表单应用程序项目添加了内置的CSRF保护。要使用此代码,请在解决方案中添加新的ASP .NET Web窗体应用程序,并查看页面后面的Site.Master代码。此解决方案将CSRF保护应用于从Site.Master页面继承的所有内容页面。
此解决方案必须满足以下要求:
•所有进行数据修改的Web表单都必须使用Site.Master页面。
•所有进行数据修改的请求都必须使用ViewState。
•该网站必须没有所有跨站点脚本(XSS)漏洞。有关详细信息,请参阅how to fix Cross-Site Scripting (XSS) using Microsoft .Net Web Protection Library。
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.");
}
}
}
}