1. What is cross-site request forgery (CSRF)
CSRF (Cross-site request forgery cross-site solicitation forgery, also known as "one click Attack" or Session Riding, usually abbreviated as CSRF or XSRF, is a malicious use of the site. Although it sounds like a cross-site script (XSS), it is very different from XSS and is almost at odds with the way it is attacked. XSS leverages trusted users within the site, while CSRF leverages trusted sites by disguising requests from trusted users. Compared to XSS attacks, csrf attacks are often less prevalent (and therefore have very few resources to protect against them) and are difficult to guard against, so they are considered more dangerous than XSS.
The above is from the Baidu Encyclopedia concept. Here's a simple example:
XSS: Assuming there is no prevention of XSS, I entered in the article Comment area: <script>while (1) alert ("hehe") </script> and successfully submitted. Then the next time you come in this page, you will continue to pop up the dialog box, so that the page can not be normal browsing, for this we output content, if the content is user input, then should be HTML Encode, such as the above script will be displayed in the form of ordinary text. Not only that, the attack script can also read the user cookie information and do anything that the script can do.
CSRF: Unlike XSS, CSRF leverages the current trusted user, allowing users to unknowingly "submit" their own data. For example, user B uploads a picture in User A's article comment area, such as:
[Img]http://images2015.cnblogs.com/blog/798800/201512/798800-20151230205214839-1087717627.jpg[/img]
Then change it to:
[Img]http://another/forgery.html[/img]
This is an invalid picture and comes from another site. In Forgery.html, the forger creates a form that points to the page to be attacked and submits the form automatically when Window.onload executes.
When user A accesses the page, it initiates a request to another/forgery.html. Because the web's authentication information is usually kept in a browser cookie, and the cookie is submitted to the server every time it is requested, the request submits the cookie and forgery.html form information to the server. The server validates the cookie and considers it a normal request to perform the relevant action.
2. Simulate a single attack
Following the idea above, we simulate an attack. Create a new MVC project with two main pages, one for displaying user names and comments, and another for users to modify their names. Just for demonstration, here we fixed a user: Zhang San. Such as:
public class CurrentUser { private static CurrentUser CurrentUser = new CurrentUser () {name= "Zhang San"}; public string Name{get;set;} public static CurrentUser current { get { return CurrentUser; }}}
The Display page is:
Another page of this site is used to modify the user's name:
<div> Modify user information: </div> <form action= "/home/update" method= "POST" > <p> <label> username:</label> <input name= "name"/> </p> <p> <input type= " Submit "/> </p> </form>
The action is update, and for the sake of security, we'll tag it with a [HttpPost] feature (it's actually authenticated here, and then the information is modified based on the user ID). Such as:
[HttpPost] Public ActionResult Update (string name) { CurrentUser.Current.Name = name; Return redirecttoaction ("Index"); }
You can see that the comment area above has a link from another site, and its code is simple, similar to our modification page, as follows:
<body> <div> <form id= "form" action= "Http://localhost:50025/home/update" method= "POST" > <input type= "hidden" name= "name" value= "2b"/> </form> </div></body>< Script type= "Text/javascript" > window.onload = function () { document.getElementById ("form"). Submit (); </script>
As you can see, the action shown on this page points to the modification page of the previous site, and is automatically submitted when the page is finished load. What happens when Zhang San clicks on this link? As follows:
3. How to Prevent
3.1 Early Prevention
Never trust user-submitted data. Usually we verify the user's input in the foreground and background to ensure the correctness and security of the data. In the example above, if the user uploads a picture and then modifies the format to. html, then it should not be saved. We can see the example of the blog park, if this can be saved, but the display is the normal text format, so that the page load will not be a request for this URL. If you look at csdn again, you will be prompted for illegal input.
Cnblogs:
Csdn
Of course, this is only the first barrier. Many websites may also have an external link as above, and if the user clicks, they may still be attacked. So we need to be more defensive.
The practice of 3.2 MVC
Before we simulated the CSRF process, we took a look at how MVC responded to this situation.
Validateantiforgeryattribute characteristics
This is a tag feature that inherits the FilterAttribute and implements the Iactionfilter, which can be applied to a controller or action. We know that the filter that implements Iactionfilter is handled before the action executes, specifically in the Onauthorization method of the Iactionfilter interface. MVC is validated in this method. How exactly is it verified?
AntiForgeryToken method
The Validateantiforgery attribute indicates that the operation needs to be validated, and we also need to use the HtmlHelper AntiForgeryToken method, which is an instance method. Specifically, this method is called in the view's form, which generates an input hidden tag named __requestverificationtoken, which is the security token. In addition, a cookie with the same name and marked as HttpOnly is generated, and the value is also a security token generated by encryption. The Onauthorization method of the Validateantiforgery attribute is validated against these two. The specific is:
1. When the user requests this page, the AntiForgeryToken method generates an input hidden and a cookie with values that are encrypted tokens.
2. The user submits the request and verifies if the action (Controller) marked the Validateantiforgery attribute.
2.1 If the form does not have an element named __requestverificationtoken, the Httpantiforgeryexception is thrown.
2.2 If there is no cookie with name __requestverificationtoken, Httpantiforgeryexception is thrown.
2.3 Parse the value of input and cookie, determine whether the match (including user name, time, etc.), the mismatch throws httpantiforgeryexception.
3. Receive an exception, display an error page, or throw in the yellow pages.
As for the value of input and the creation of a cookie, MVC is generated internally based on the current user name, time, and collection MachineKey, ensuring that it is not easily guessed. Interested friends can learn the detailed process through the source code.
According to the above procedure, we add a [validateantiforgery] feature to the update, and the table is monotonic with the HtmlHelper AntiForgeryToken method. at this point, if the user clicked on the link, the same access to the forgery.html, and the automatic submission of the form, the cookie will be submitted, but the forgery page cannot know the value of input hidden, so cannot pass the validation.
the practice of 3.3 WebForm
WebForm no AntiForgeryToken method can be used directly, but when we know the implementation process of MVC, we can also implement a set of our own.
In the page form, like MVC, we also output an input hidden tag named: _requestverificationtoken, with a value of the serialized token, specifically called Httprespose extension method for AntiForgeryToken. The AntiForgeryToken method will not only enter input hidden, The GUID is also stored in Context.item, which is a collection that can be used at various times within a single request, and after the page cycle is complete, we determine if there is a tag, and if so, it needs to be written to the cookie.
Form:
<form id= "Form1" action= "updateanticsrf.aspx" method= "POST" runat= "Server" > <div> <%= Response.antiforgerytoken ()%> <input type= "text" name= "name"/> <input type= "Submit"/> </div> </form>
AntiForgeryToken extension methods:
public static class Httpresposeextentions {public static string AntiForgeryToken (this httpresponse response) c3/>{ HttpContext context = HttpContext.Current; if (context = = null) { throw new InvalidOperationException ("Invalid request! "); } GUID guid = Guid.NewGuid (); Context. items["_requestverificationtoken"] = GUID; ObjectStateFormatter formatter = new ObjectStateFormatter (); return string. Format ("<input type= ' hidden ' name= ' _requestverificationtoken ' value={0}/>", Formatter. Serialize (GUID)); } }
For validating tokens, and writing a GUID to a cookie is done through a anticsrfmodule, it primarily intercepts both pre-and post-execution events of the page. After the page executes, it is necessary to write the GUID to the cookie, and before the page executes, it is judged whether it needs to be validated, and the result is validated, and throws an exception if it does not match. The code is as follows:
public class Anticsrfmodule:ihttpmodule {public void Dispose () {} public void Init (HttpApplication app) {app. PreRequestHandlerExecute + = new EventHandler (App_prerequesthandlerexecute); App. PostRequestHandlerExecute + = new EventHandler (App_postrequesthandlerexecute); } void App_prerequesthandlerexecute (object sender, EventArgs e) {HttpContext context = ( (HttpApplication) sender). Context; HttpRequest request = context. Request; IHttpHandler Handler = context. Handler; if (handler. GetType (). IsDefined (typeof (Validationantiforgeryattribute), true)) {if (Request. Httpmethod.equals ("POST", Stringcomparison.currentcultureignorecase)) {HttpCookie Cooki E = Request. cookies["_requestverificationtoken"]; if (cookie = = null) {throw new INVAlidoperationexception ("Invalid request! "); } String value = Request. form["_requestverificationtoken"]; if (string. IsNullOrEmpty (value)) {throw new InvalidOperationException ("Invalid request! "); } objectstateformatter Formatter = new ObjectStateFormatter (); Guid? GUID = Formatter. Deserialize (value) as Guid?; if (GUID. HasValue && GUID. value.tostring () = = Cookie. Value) {return; } throw new InvalidOperationException ("Invalid request! "); }}} void App_postrequesthandlerexecute (object sender, EventArgs e) {Httpcont Ext context = ((HttpApplication) sender). Context; Guid? GUID = context. items["_requestverificationtoken"] as Guid?; if (GUID. HasValue) {HttpCookie cookie = new HttpCookie ("_requestverificationtoken", GUID. Value.tostring ()); Cookies. HttpOnly = false; Context. RESPONSE.COOKIES.ADD (cookie); } } }
For pages that require validation, a Validateantiforgeryattribute attribute is marked as follows:
public class Validateantiforgeryattribute:attribute { }
Again, we simulate an attack as before. The result, as we thought, would be to throw in the yellow pages.
3.4 Ajax Way
We are all submitting the data through the post form, if it is submitted in Ajax? We can judge in the background whether the request is an AJAX request, and if not, the operation is not allowed. Because JS is restricted by the same-origin policy, the script cannot communicate with this domain without being authorized by the other domain. That is, another/forgery.html can submit data to us in the form of post, but there is no way to submit it in the form of Ajax, or to invoke the method of our page or access the DOM element.
4. The realization of the blog Park
The example is on the side. We see the blog Park "set up basic information" module, see the source code will find here use this technology.
Form:
Cookies:
Cross-site Request forgery