Thursday, June 26, 2014

Cross-Site Request Forgery (CSRF) and ASP.NET MVC Prevention

There are two main types of easily destructive holes in a web/software design to be aware of currently. There is Cross-site scripting (XSS) which is found in applications across the web where a malicious attack can inject client-side script into Web pages. About 4/5 of the security vulnerabilities in 2007 were caused by XSS according to Symantec. Since XSS has been such a big deal since then, people have taken many precautions to deal with this issue.

However, a second breach to watch out for is cross-site request forgery (CSRF/XSRF). CSRF works on the other side of things than XSS. While XSS is an attack to the website application, CSRF submits to the client software. How does it do this? Well, the attacker creates their own HTML form and uploads it to their own server, disguises it as your site, lures someone to their link instead, and then when the form on their host is submitted.. it will go to your website server and change their email address to the attackers. Then, the attacker can just request to have "their" password (victim's password) sent to this email address. And viola they have stolen someone's account and password, AND their email is now in the server database so there it little hope for recovery of the the victim's account (really bad when credit card numbers are associated with this occurrence, if you can imagine!).

I will take a sample from an online form where you are editing a Person inside of the Controller that uses the ASP.NET MVC package containing the AntiForgeryToken() helper.

        /// 
        /// To edit a client. 
        /// POST: /Register/Edit/5
        /// 
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Person person)
        {
            if (ModelState.IsValid)
            {
                db.Entry(client).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("List");
            }
            return View(person);
        }

On your view you need to insert this also into the HTML:

        @using (Html.BeginForm())
        {
            @Html.AntiForgeryToken()
            @Html.ValidationSummary(true)

The ASP.NET MVC package makes it pretty easy to prevent this! It is very simple in its mechanism: under normal circumstances any incoming requests will be given a RequestVerificationToken that has to match the Request.Form, and things will be just fine if the user is on the actual correct website. However, if someone got lured to the wrong site then the attacker's fake site cannot know what the RequestVerificationToken cookie should be.. therefore the system will show a failure message and not allow information to be edited (hence preventing the swap out of email addresses). Its a small piece of code, it works well, and doesn't change anything else assuming all is going well and everyone is on the same page (literally!).

While this is not something most people need to worry about, but for large sites with many viewers should do this. And, it never hurts to be careful and start doing good practice with small sites! Who knows if your site will grow large one day? Its just a good concept to know and be aware of what is out there and how everything works together when building websites/software/databases! The more you know how to take something down, the better you can secure your own things!

Lastly, this only works if the users allow cookies in their browser, you MUST cover up your XSS breaches ALSO (otherwise the attacker is just going to snag out the token value), and the browser being used must be able to implement the program (as usual!).. but if you're using one of the main ones and a relatively current version this should not even be a concern.