2008-10-20 7 views
0

Je suis à la recherche d'une solution abstraite de classe de base ou de page maître qui empêchera quiconque de faire XSRF en utilisant à la fois un token et un ttl. Est-ce que quelqu'un peut-il me montrer la bonne direction? Editer: La solution idéale tirera parti du cookie que le fournisseur d'appartenance par défaut envoie au client.Quelqu'un peut-il suggérer une classe de base abstraite pour empêcher XSRF dans .NET 2.0+

+0

Si elle était aussi simple que cela, ils avaient le construire en tant correctif de sécurité du framework .Net. –

+0

ASP.NET MVC? Vanilla ASP.NET? Autre chose? –

Répondre

3

Vous pouvez placer un champ masqué sur votre page maître, générer une clé pendant l'événement Page_Load de votre page maître, affecter la clé en tant que valeur de votre champ masqué, puis ajouter cette valeur à votre cookie. Ensuite, vous comparez simplement ces valeurs.

0

J'ai démarré une classe de base qu'une page maître peut hériter. J'ai opté d'utiliser viewstate au lieu de mettre une entrée cachée parce qu'avec cette approche je n'ai pas besoin de m'inquiéter de plusieurs formes sur une page/etc. Il faut aussi un peu plus de travail pour trouver cette valeur qu'une simple "source de vue"

Voici quelques problèmes que j'essaie de corriger.

  • Quand j'actualisez la page (pas post-retour) l'état d'affichage, et caché entrée , (quand j'ai commencé cette approche) valeurs ne sont pas mis à jour comme le cookie est

  • Quand je naviguer vers une nouvelle page dans mon application, la nouvelle page commence sans état d'affichage valable et donc ma comparaison échoue dans ce cas ...

Ce qui suit est mon travail en cours;)

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; } 
    } 

} 
Questions connexes