谁能建议一个抽象基类来防止 .NET 2.0 中的 XSRF?

发布于 2024-07-07 18:14:19 字数 117 浏览 5 评论 0原文

我正在寻找一个抽象基类或母版页解决方案,以防止任何人同时使用令牌和 ttl 执行 XSRF。 有人能指出我正确的方向吗?

编辑:理想的解决方案将利用默认会员资格提供商发送给客户端的 cookie。

I'm looking for an abstract base class or master page solution that will prevent anyone from doing XSRF using both a token and ttl. Can anyone point me in the right direction?

Edit: The ideal solution will leverage the cookie that the default membership provider sends down to the client.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初雪 2024-07-14 18:14:19

您可以在母版页上放置一个隐藏字段,在母版页的 Page_Load 事件期间生成一个键,将该键指定为隐藏字段的值,然后将该值添加到您的 cookie 中。 然后你只需比较这些值即可。

You could put a hidden field on your masterpage, generate a key during the Page_Load event of your master page, assign the key as the value of your hidden field and then add that value to your cookie. Then you just compare those values.

肥爪爪 2024-07-14 18:14:19

我启动了一个母版页可以继承的基类。 我选择使用视图状态而不是放置隐藏输入,因为使用这种方法我不需要担心页面上的多个表单等。 与简单的“查看源代码”相比,找到这个值还需要更多的工作。

下面是我试图纠正的一些问题。

  • 当我刷新页面时(不是
    回发)视图状态,并隐藏
    输入,(当我开始这种方法时)
    不是

  • 当我导航到新页面时,

    我的应用程序,新页面开始
    没有有效的视图状态,因此
    在这种情况下,我的比较失败...

以下是我正在进行的工作;)

 public class PreventXSRF : MasterPage
 {

     HttpCookie mCookie = null;
     FormsAuthenticationTicket mPreviousAuthenticationTicket = null;
     FormsAuthenticationTicket mNewAuthenticationTicket = null;

     public bool IsXSRF()
     {
         if ((Request.Cookies(".ASPXAUTH") != null)) {
             mCookie = Request.Cookies(".ASPXAUTH");
             //get the current auth ticket so we can verify the token (userData) matches the value of the hidden input
             mPreviousAuthenticationTicket = FormsAuthentication.Decrypt(mCookie.Value);
         }
         else {
             ///'the membership cookie does not exist so this is not an authenticated user
             return true;
         }

         //** ** **
         // verify the cookie value matches the viewstate value
         // if it does then verify the ttl is valid
         //** ** **

         if ((mPreviousAuthenticationTicket != null)) {
             if (mPreviousAuthenticationTicket.UserData == Token) {
                 if ((TTL != null)) {
                     if (Convert.ToDateTime(TTL).AddMinutes(5) < DateTime.Now()) {
                         ///'the ttl has expired so this is not a valid form submit
                         return true;
                     }
                 }
                 else {
                     //** ** **
                     // ?? what about a hack that could exploit this when a user tries to BF
                     // a value for the token and simply keeps the viewstate for ttl null ??
                     //** ** **
                 }
             }
             else {
                 //** ** **
                 // ?? I hit this when I navigate to another page in the app (GET)
                 // in this event, it was hit because the cookie has a valid token
                 // but the page is new so viewstate is not valid ... ??
                 //** ** **
                 ///'the cookie value does not match the form so this is not a valid form submit
                 return true;
             }
         }
         else {
             ///'the authentication ticket does not exist so this is not a valid form submit
             return true;
         }

         //** ** **
         // if the code gets this far the form submit is 99.9% valid, so now we gen a new token
         // and set this new value on the auth cookie and reset the viewstate value
         // so it matches the cookie
         //** ** **

         //gen a new ttl and set the viewstate value
         TTL = GenerateTTL();
         //gen a new token and set the viewstate value
         Token = GenerateToken();

         if ((mPreviousAuthenticationTicket != null)) {
             //** ** **
             // create a new authticket using the current values + a custom token
             // we are forced to do this because the current cookie is read-only
             // ** ** **
             mNewAuthenticationTicket = new FormsAuthenticationTicket(mPreviousAuthenticationTicket.Version, mPreviousAuthenticationTicket.Name, mPreviousAuthenticationTicket.IssueDate, mPreviousAuthenticationTicket.Expiration, mPreviousAuthenticationTicket.IsPersistent, Token);
         }
         else {
             ///'TODO: if no auth ticket exists we need to return as this won't be valid
         }

         if ((mCookie != null)) {
             //** ** **
             // take the new auth ticket with the userdata set to the new token value
             // encrypt this, update the cookie, and finally apply this to the users machine
             //** ** **
             mCookie.Value = FormsAuthentication.Encrypt(mNewAuthenticationTicket);
             Response.Cookies.Add(mCookie);
         }
         else {
             ///'TODO: if no cookie exists we need to return as this won't be valid
         }

         //if we got this far without a return true, it must not be a xsrf exploit so return false
         return false;
     }

     private string GenerateToken()
     {
         RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
         byte[] randBytes = new byte[32];
         random.GetNonZeroBytes(randBytes);
         return Convert.ToBase64String(randBytes);
     }

     private string GenerateTTL()
     {
         return DateTime.Now();
     }

     private string TTL {
         get { return ViewState("TTL"); }
         set { ViewState("TTL") = value; }
     }

     private string Token {
         get { return ViewState("Token"); }
         set { ViewState("Token") = value; }
     }

 }

I started a base class that a master page can inherit. I opt'd to use viewstate instead of putting a hidden input down because with this approach I don't need to worry about multiple forms on a page/etc. It also takes a little more work to find this value than a simple "view source"

The below are a few issues that I'm trying to correct.

  • When I refresh the page (not
    post-back) the viewstate,and hidden
    input, (when I started this approach)
    values are not updated like the cookie is

  • When I navigate to a new page inside
    my app, the new page starts
    without the valid viewstate and thus
    my compare fails for this case ...

The below is my work in progress ;)

 public class PreventXSRF : MasterPage
 {

     HttpCookie mCookie = null;
     FormsAuthenticationTicket mPreviousAuthenticationTicket = null;
     FormsAuthenticationTicket mNewAuthenticationTicket = null;

     public bool IsXSRF()
     {
         if ((Request.Cookies(".ASPXAUTH") != null)) {
             mCookie = Request.Cookies(".ASPXAUTH");
             //get the current auth ticket so we can verify the token (userData) matches the value of the hidden input
             mPreviousAuthenticationTicket = FormsAuthentication.Decrypt(mCookie.Value);
         }
         else {
             ///'the membership cookie does not exist so this is not an authenticated user
             return true;
         }

         //** ** **
         // verify the cookie value matches the viewstate value
         // if it does then verify the ttl is valid
         //** ** **

         if ((mPreviousAuthenticationTicket != null)) {
             if (mPreviousAuthenticationTicket.UserData == Token) {
                 if ((TTL != null)) {
                     if (Convert.ToDateTime(TTL).AddMinutes(5) < DateTime.Now()) {
                         ///'the ttl has expired so this is not a valid form submit
                         return true;
                     }
                 }
                 else {
                     //** ** **
                     // ?? what about a hack that could exploit this when a user tries to BF
                     // a value for the token and simply keeps the viewstate for ttl null ??
                     //** ** **
                 }
             }
             else {
                 //** ** **
                 // ?? I hit this when I navigate to another page in the app (GET)
                 // in this event, it was hit because the cookie has a valid token
                 // but the page is new so viewstate is not valid ... ??
                 //** ** **
                 ///'the cookie value does not match the form so this is not a valid form submit
                 return true;
             }
         }
         else {
             ///'the authentication ticket does not exist so this is not a valid form submit
             return true;
         }

         //** ** **
         // if the code gets this far the form submit is 99.9% valid, so now we gen a new token
         // and set this new value on the auth cookie and reset the viewstate value
         // so it matches the cookie
         //** ** **

         //gen a new ttl and set the viewstate value
         TTL = GenerateTTL();
         //gen a new token and set the viewstate value
         Token = GenerateToken();

         if ((mPreviousAuthenticationTicket != null)) {
             //** ** **
             // create a new authticket using the current values + a custom token
             // we are forced to do this because the current cookie is read-only
             // ** ** **
             mNewAuthenticationTicket = new FormsAuthenticationTicket(mPreviousAuthenticationTicket.Version, mPreviousAuthenticationTicket.Name, mPreviousAuthenticationTicket.IssueDate, mPreviousAuthenticationTicket.Expiration, mPreviousAuthenticationTicket.IsPersistent, Token);
         }
         else {
             ///'TODO: if no auth ticket exists we need to return as this won't be valid
         }

         if ((mCookie != null)) {
             //** ** **
             // take the new auth ticket with the userdata set to the new token value
             // encrypt this, update the cookie, and finally apply this to the users machine
             //** ** **
             mCookie.Value = FormsAuthentication.Encrypt(mNewAuthenticationTicket);
             Response.Cookies.Add(mCookie);
         }
         else {
             ///'TODO: if no cookie exists we need to return as this won't be valid
         }

         //if we got this far without a return true, it must not be a xsrf exploit so return false
         return false;
     }

     private string GenerateToken()
     {
         RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
         byte[] randBytes = new byte[32];
         random.GetNonZeroBytes(randBytes);
         return Convert.ToBase64String(randBytes);
     }

     private string GenerateTTL()
     {
         return DateTime.Now();
     }

     private string TTL {
         get { return ViewState("TTL"); }
         set { ViewState("TTL") = value; }
     }

     private string Token {
         get { return ViewState("Token"); }
         set { ViewState("Token") = value; }
     }

 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文