2009-08-24 90 views
16

我有一个.NET Webforms站点感谢需要张贴到我的MVC应用程序,当前作为一个单独的应用程序位于Webform站点内。在WebForms中生成AntiForgeryToken

Webform应用程序需要将一些敏感值发布到MVC应用程序。

有没有办法在我的WebForms应用程序中生成AntiForgeryToken(),以便它可以通过表单发送。

否则有谁知道任何其他自定义防伪代码,这将允许我做类似于MVC的AntiForgeryValidation。

回答

8

自己实施并不难。

  • 生成一个GUID
  • 把它放在一个隐藏字段
  • 也把它的Session或Cookie的(在后一种情况下,具有一定的防篡改保护)
  • 在处理的开始形式比较字段和存储的令牌。

(如果你看一下MVC的实现,很少有更给它。有几个辅助方法是你所需要的。)

+1

任何代码来说明如何做到这一点? – 2015-08-10 07:40:59

+2

@ShekharPankaj请参阅[OWASP .NET安全备忘单](https://www.owasp.org/index.php/.NET_Security_Cheat_Sheet#ASP.NET_Web_Forms_Guidance)。确保你在整合之前了解它(即它保护你的东西,更重要的是它不能保护你)(http://security.stackexchange.com/q/59470))。 – tne 2015-12-14 11:48:56

2

的WebForms在Page.ViewStateUserKey一个非常类似的模拟。通过setting that to a per-user value(大多数选择HttpSessionState.SessionId),WebForms将验证作为the MAC check的一部分的ViewState 。

overrides OnInit(EventArgs e) { 
    base.OnInit(e); 
    ViewStateUserKey = Session.SessionId; 
} 

有场景中ViewStateUserKey will not help。主要是,他们归结为GET请求(或者在Page_Load中没有检查IsPostback)做危险的事情,或者禁用ViewStateMAC。

1

您可以使用反射来获取用于设置用于MVC验证的cookie和匹配表单输入的MVC方法。这样,您可以通过[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken]属性来进行MVC操作,您可以从WebForms生成的页面发布该属性。

看到这个答案:Using an MVC HtmlHelper from a WebForm

7

这是一个老问题,但对于Web表单最新的Visual Studio 2012 ASP.NET模板包括烘焙到主网页防CSRF代码。如果你没有模板,这里是它生成的代码:

Protected Sub Page_Init(sender As Object, e As System.EventArgs) 


    ' The code below helps to protect against XSRF attacks 
    Dim requestCookie As HttpCookie = Request.Cookies(AntiXsrfTokenKey) 
    Dim requestCookieGuidValue As Guid 
    If ((Not requestCookie Is Nothing) AndAlso Guid.TryParse(requestCookie.Value, requestCookieGuidValue)) Then 
     ' 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 

     Dim responseCookie As HttpCookie = New HttpCookie(AntiXsrfTokenKey) With {.HttpOnly = True, .Value = _antiXsrfTokenValue} 
     If (FormsAuthentication.RequireSSL And Request.IsSecureConnection) Then 
      responseCookie.Secure = True 
     End If 
     Response.Cookies.Set(responseCookie) 
    End If 

    AddHandler Page.PreLoad, AddressOf master_Page_PreLoad 
End Sub 

Private Sub master_Page_PreLoad(sender As Object, e As System.EventArgs) 


    If (Not IsPostBack) Then 
     ' Set Anti-XSRF token 
     ViewState(AntiXsrfTokenKey) = Page.ViewStateUserKey 
     ViewState(AntiXsrfUserNameKey) = If(Context.User.Identity.Name, String.Empty) 
    Else 
     ' Validate the Anti-XSRF token 
     If (Not DirectCast(ViewState(AntiXsrfTokenKey), String) = _antiXsrfTokenValue _ 
      Or Not DirectCast(ViewState(AntiXsrfUserNameKey), String) = If(Context.User.Identity.Name, String.Empty)) Then 
      Throw New InvalidOperationException("Validation of Anti-XSRF token failed.") 
     End If 
    End If 
End Sub 
+1

优秀的文章,但是你错过了3行,其中声明了AntiXsrfTokenKey和AntiXsrfUserNameKey以及_antiXsrfTokenValue。可能有助于更新一些:-) – EvilDr 2014-07-08 13:44:34

+0

@IanIppolito此代码是否会验证直接处理程序的请求?因为那时我认为这个代码不会被执行。 – 2014-09-10 15:06:08

+0

您好,先生,我使用VS2013和.Net FrameWork 4.5创建我的ASP.net网页表单应用程序,但我的母版页不包含此自动生成的代码,我如何知道我的网站是否从CSRF安全? – 2015-04-29 09:20:53

3

伊恩·伊波利托答案这里的C#版本:

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) 
    { 
     // 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."); 
      } 
     } 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 
} 
+0

是否需要使用上下文中的用户标识进行验证?当页面之间的上下文继续时,视图状态将保持该页面的状态。如果在验证运行的时候身份更改(通过浏览多个选项卡),它将引发异常,因为ViewState不会发生更改。 – Tristan 2017-12-21 19:47:31