Hi,
I have a vs2013 web app and I am trying to add csrf protection.
I tried inserting the following code to the MasterPage:
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."); } } }
In addition, the application also has a page that is not a content page and it can be opened from one of the content pages using <a> tag (example_Form.aspx).
I added the following code to the example_Form.aspx:
////anti forgery variables 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."); } } }
Do I also need to add a hidden field to the content page?
To test my code I wrote the following HTML to try and hack my app:
<html><head> <title>test csrf forgery</title> <script type ="text/javascript"> document.form1.submit(); document.getElementById("ButtonSaveOkay").click(); </script></head><body> <form method="post" action="http://www.example.com/example_Form.aspx?TABLE=MD&STATUS=1" onsubmit="javascript:return WebForm_OnSubmit();" id="form1"> <div class="aspNetHidden"> <input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" /> <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" /> <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" /> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTIzNjYzNTUyOQ8PFhIeBmZvcm1JRGYeEVBvc3RCYWNrQ29udHJvbElEZR4GcmVjU3RyFRMAAAAAAAAAAAAAAAAAAAAAAAAAHg9fX0FudGlYc3JmVG9rZW4FIDg0ZTZlNWFkYjA4YzQ1MTBhZjAxZjAxNWJiMDI5MjY3HhJfX0FudGlYc3JmVXNlck5hbWUFBnNoYXZpdB4IYXBwX0NvZGUFAk1EHhJwZXJtaXNzaW9uc19wYXJhbXMVCgExATEBMQExATEBMQExATEBMQExHg5UQkxfY29kZV9hbGlhcwUCTUQeCmZvcm1TdGF0dXMCAWQWAgIDDxYCHgVzdHlsZQUZaGVpZ2h0OjI0MW1tO3dpZHRoOjMzMm1tOxYCAgUPZBYCZg9kFgQCAQ8PFgQeBVdpZHRoGwAAAAAAwHRABQAAAB4EXyFTQgKAAmQWHAIBDw8WAh4HVmlzaWJsZWhkZAIDDw8WAh8MaGRkAgUPDxYCHwxoZGQCBw8PFgIfDGhkZAIJDw8WCB4EVGV4dAULVXBkYXRlIE1vZGUeCUJhY2tDb2xvcgkApv//HglGb3JlQ29sb3IJ/////x8LAgxkZAILDw8WBB4ISW1hZ2VVcmwFH34vSW1hZ2VzL21lbnUtZmlyc3QtaWNvbl9CVy5wbmceB0VuYWJsZWRoZGQCDQ8PFgQfEAUifi9JbWFnZXMvbWVudS1wcmV2aW91cy1pY29uX0JXLnBuZx8RaGRkAg8PDxYCHxAFFn4vSW1hZ2VzL3NhdmUtaWNvbi5wbmdkZAIRDw8WBB8QBR5+L0ltYWdlcy9tZW51LW5leHQtaWNvbl9CVy5wbmcfEWhkZAITDw8WBB8QBR5+L0ltYWdlcy9tZW51LWxhc3QtaWNvbl9CVy5wbmcfEWhkZAIVDw8WAh8MaGRkAhcPD2QWAh8JBUFjdXJzb3I6cG9pbnRlcjtwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjMyNW1tO3RvcDowcHg7ei1pbmRleDo1MDAwO2QCGQ8PFgIfDGgWAh8JBUFjdXJzb3I6cG9pbnRlcjtwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjMxMm1tO3RvcDowcHg7ei1pbmRleDo1MDAwO2QCGw8PFgIfDGgWAh8JBUFjdXJzb3I6cG9pbnRlcjtwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjMyMm1tO3RvcDowcHg7ei1pbmRleDo1MDAwO2QCAw9kFgJmD2QWAgIBD2QWAgIFD2QWAmYPZBYCAgUPPCsAEQIBEBYAFgAWAAwUKwAAZBgCBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WBgUFZmlyc3QFBHByZXYFBHNhdmUFBG5leHQFBGxhc3QFC2NhbmNlbF9lZGl0BQlHcmlkVmlldzEPZ2QX4X+IaA2x4/eX9oSreJxyBUBi1YaUmTent46Jf56oFA==" /> </div> <h1>test csrf forgery</h1> <div id="form_fields"> <div id="UpdatePanel_fields"> <div id="MainForm" style="text-align:center;"> <input name="x_2" type="text" readonly="readonly" id="x_2" size="6" style="background-color:#EBEBE4;left:2mm;top:1mm;position:absolute;z-index:2;text-align:center;font-size:12px;font-family:monospace;" /> <input name="D_5" type="text" id="D_5" value="20180101" /> <input name="D_7" type="text" id="D_7" value="20181231" /> <input type="submit" name="ButtonSaveOkay" value="save" id="ButtonSaveOkay" /> </div> </div> </div> </form>></body></html>
I logged in to my example.com application and then I opened the HTML code located on my computer. I clicked the submit button and I managed to save a new record using the form.
What am I missing? What am I doing wrong?
I tried running the html code while directing the form action to my localhost, while debugging, and I could see that the HTML file has no problem running server side script. The token is the same. a new Anti-XSRF token is never created.
I would really appreciate your help.