code_junkie

Can anyone suggest an abstract base class to prevent XSRF in .NET 2.0+

Nov 11th, 2011
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.44 KB | None | 0 0
  1. public class PreventXSRF : MasterPage
  2. {
  3.  
  4. HttpCookie mCookie = null;
  5. FormsAuthenticationTicket mPreviousAuthenticationTicket = null;
  6. FormsAuthenticationTicket mNewAuthenticationTicket = null;
  7.  
  8. public bool IsXSRF()
  9. {
  10. if ((Request.Cookies(".ASPXAUTH") != null)) {
  11. mCookie = Request.Cookies(".ASPXAUTH");
  12. //get the current auth ticket so we can verify the token (userData) matches the value of the hidden input
  13. mPreviousAuthenticationTicket = FormsAuthentication.Decrypt(mCookie.Value);
  14. }
  15. else {
  16. ///'the membership cookie does not exist so this is not an authenticated user
  17. return true;
  18. }
  19.  
  20. //** ** **
  21. // verify the cookie value matches the viewstate value
  22. // if it does then verify the ttl is valid
  23. //** ** **
  24.  
  25. if ((mPreviousAuthenticationTicket != null)) {
  26. if (mPreviousAuthenticationTicket.UserData == Token) {
  27. if ((TTL != null)) {
  28. if (Convert.ToDateTime(TTL).AddMinutes(5) < DateTime.Now()) {
  29. ///'the ttl has expired so this is not a valid form submit
  30. return true;
  31. }
  32. }
  33. else {
  34. //** ** **
  35. // ?? what about a hack that could exploit this when a user tries to BF
  36. // a value for the token and simply keeps the viewstate for ttl null ??
  37. //** ** **
  38. }
  39. }
  40. else {
  41. //** ** **
  42. // ?? I hit this when I navigate to another page in the app (GET)
  43. // in this event, it was hit because the cookie has a valid token
  44. // but the page is new so viewstate is not valid ... ??
  45. //** ** **
  46. ///'the cookie value does not match the form so this is not a valid form submit
  47. return true;
  48. }
  49. }
  50. else {
  51. ///'the authentication ticket does not exist so this is not a valid form submit
  52. return true;
  53. }
  54.  
  55. //** ** **
  56. // if the code gets this far the form submit is 99.9% valid, so now we gen a new token
  57. // and set this new value on the auth cookie and reset the viewstate value
  58. // so it matches the cookie
  59. //** ** **
  60.  
  61. //gen a new ttl and set the viewstate value
  62. TTL = GenerateTTL();
  63. //gen a new token and set the viewstate value
  64. Token = GenerateToken();
  65.  
  66. if ((mPreviousAuthenticationTicket != null)) {
  67. //** ** **
  68. // create a new authticket using the current values + a custom token
  69. // we are forced to do this because the current cookie is read-only
  70. // ** ** **
  71. mNewAuthenticationTicket = new FormsAuthenticationTicket(mPreviousAuthenticationTicket.Version, mPreviousAuthenticationTicket.Name, mPreviousAuthenticationTicket.IssueDate, mPreviousAuthenticationTicket.Expiration, mPreviousAuthenticationTicket.IsPersistent, Token);
  72. }
  73. else {
  74. ///'TODO: if no auth ticket exists we need to return as this won't be valid
  75. }
  76.  
  77. if ((mCookie != null)) {
  78. //** ** **
  79. // take the new auth ticket with the userdata set to the new token value
  80. // encrypt this, update the cookie, and finally apply this to the users machine
  81. //** ** **
  82. mCookie.Value = FormsAuthentication.Encrypt(mNewAuthenticationTicket);
  83. Response.Cookies.Add(mCookie);
  84. }
  85. else {
  86. ///'TODO: if no cookie exists we need to return as this won't be valid
  87. }
  88.  
  89. //if we got this far without a return true, it must not be a xsrf exploit so return false
  90. return false;
  91. }
  92.  
  93. private string GenerateToken()
  94. {
  95. RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
  96. byte[] randBytes = new byte[32];
  97. random.GetNonZeroBytes(randBytes);
  98. return Convert.ToBase64String(randBytes);
  99. }
  100.  
  101. private string GenerateTTL()
  102. {
  103. return DateTime.Now();
  104. }
  105.  
  106. private string TTL {
  107. get { return ViewState("TTL"); }
  108. set { ViewState("TTL") = value; }
  109. }
  110.  
  111. private string Token {
  112. get { return ViewState("Token"); }
  113. set { ViewState("Token") = value; }
  114. }
  115.  
  116. }
Add Comment
Please, Sign In to add comment