WebForms 应用程序中的 ValidateAntiForgeryToken

Dov*_*ler 6 c# asp.net webforms csrf-protection

我已经阅读了一些关于使用ValidateAntiForgeryToken防止 XSRF/CSRF 攻击的文章。然而,我所看到的似乎只与 MVC 相关。

这些是我看过的文章:

ValidateAntiForgeryToken 用途、解释和示例

CSRF 和 AntiForgeryToken

ASP.NET MVC 和网页中的 XSRF/CSRF 预防

我如何在 WebForms 应用程序中实现这个或类似的东西?

Dov*_*ler 7

我找到了这篇文章How To Fix Cross-Site Request Forgery (CSRF) using Microsoft .Net ViewStateUserKey and Double Submit Cookie,其中包含以下信息代码和说明:

\n\n
\n

从 Visual Studio 2012 开始,Microsoft 向新的 Web 表单应用程序项目添加了内置 CSRF 保护。要利用此代码,请将新的 ASP .NET Web 窗体应用程序添加到您的解决方案并查看 Site.Master 代码隐藏页面。此解决方案将对从 Site.Master 页面继承的所有内容页面应用 CSRF 保护。

\n\n

要使该解决方案发挥作用,必须满足以下要求:

\n\n

\xe2\x80\xa2所有进行数据修改的 Web 表单都必须使用 Site.Master\n 页面。

\n\n

\xe2\x80\xa2所有进行数据修改的请求都必须使用ViewState。

\n\n

\xe2\x80\xa2该网站必须不存在所有跨站脚本 (XSS)\n 漏洞。有关详细信息,请参阅如何使用 Microsoft .Net Web 保护库修复跨站点脚本 (XSS)

\n
\n\n
public partial class SiteMaster : MasterPage\n{\nprivate const string AntiXsrfTokenKey = "__AntiXsrfToken";\nprivate const string AntiXsrfUserNameKey = "__AntiXsrfUserName";\nprivate string _antiXsrfTokenValue;\n\nprotected void Page_Init(object sender, EventArgs e)\n{\n    //First, check for the existence of the Anti-XSS cookie\n    var requestCookie = Request.Cookies[AntiXsrfTokenKey];\n    Guid requestCookieGuidValue;\n\n    //If the CSRF cookie is found, parse the token from the cookie.\n    //Then, set the global page variable and view state user\n    //key. The global variable will be used to validate that it matches in the view state form field in the Page.PreLoad\n    //method.\n    if (requestCookie != null\n    && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))\n    {\n        //Set the global token variable so the cookie value can be\n        //validated against the value in the view state form field in\n        //the Page.PreLoad method.\n        _antiXsrfTokenValue = requestCookie.Value;\n\n        //Set the view state user key, which will be validated by the\n        //framework during each request\n        Page.ViewStateUserKey = _antiXsrfTokenValue;\n    }\n    //If the CSRF cookie is not found, then this is a new session.\n    else\n    {\n        //Generate a new Anti-XSRF token\n        _antiXsrfTokenValue = Guid.NewGuid().ToString("N");\n\n        //Set the view state user key, which will be validated by the\n        //framework during each request\n        Page.ViewStateUserKey = _antiXsrfTokenValue;\n\n        //Create the non-persistent CSRF cookie\n        var responseCookie = new HttpCookie(AntiXsrfTokenKey)\n        {\n            //Set the HttpOnly property to prevent the cookie from\n            //being accessed by client side script\n            HttpOnly = true,\n\n            //Add the Anti-XSRF token to the cookie value\n            Value = _antiXsrfTokenValue\n        };\n\n        //If we are using SSL, the cookie should be set to secure to\n        //prevent it from being sent over HTTP connections\n        if (FormsAuthentication.RequireSSL &&\n        Request.IsSecureConnection)\n        responseCookie.Secure = true;\n\n        //Add the CSRF cookie to the response\n        Response.Cookies.Set(responseCookie);\n    }\n\n        Page.PreLoad += master_Page_PreLoad;\n    }\n\n    protected void master_Page_PreLoad(object sender, EventArgs e)\n    {\n        //During the initial page load, add the Anti-XSRF token and user\n        //name to the ViewState\n        if (!IsPostBack)\n        {\n            //Set Anti-XSRF token\n            ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;\n\n            //If a user name is assigned, set the user name\n            ViewState[AntiXsrfUserNameKey] =\n            Context.User.Identity.Name ?? String.Empty;\n        }\n        //During all subsequent post backs to the page, the token value from\n        //the cookie should be validated against the token in the view state\n        //form field. Additionally user name should be compared to the\n        //authenticated users name\n        else\n        {\n            //Validate the Anti-XSRF token\n            if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue\n            || (string)ViewState[AntiXsrfUserNameKey] !=\n            (Context.User.Identity.Name ?? String.Empty))\n        {\n        throw new InvalidOperationException("Validation of\n        Anti-XSRF token failed.");\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

}

\n


小智 6

CSRF 攻击不仅限于 MVC 应用程序,webforms 也容易受到攻击。

基本上,CSRF 攻击利用网站在用户浏览器中的信任,通过向网站请求或发布信息,通常通过恶意网站内的隐藏表单或 JavaScript XMLHttpRequests,作为用户使用存储在浏览器中的 cookie。

为了防止这种攻击,您需要一个防伪令牌,一个在您的表单中发送的唯一令牌,您需要在信任表单信息之前对其进行验证。

您可以在此处找到详细说明。

为了保护您的 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");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的母版页中实现这一点:

MyMasterPage.Master.cs:

protected void Page_Load(object sender, EventArgs e)
{
    CsrfHandler.Validate(this.Page, forgeryToken);
    ...
}
Run Code Online (Sandbox Code Playgroud)

我的大师.大师:

<form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
    <asp:HiddenField ID="forgeryToken" runat="server"/>
    ...
</form>
Run Code Online (Sandbox Code Playgroud)

希望你会发现这很有用。