今天学习ASP.NET MVC时,其中介绍了一种如何解决一种叫Cross-site request forgery网站攻击的方法(链接:Stephen Walther博客 http://stephenwalther.com/archive/2009/03/03/chapter-6-understanding-html-helpers.aspx)。
Cross-site request forgery简单来说就是利用受信任的网站A使用cookie做安全认证时,恶意网站可以偷偷的用一个A网站的链接(比如图片)或者脚本,在用户不知情的情况下想网站A提交Http请求,进行相关操作,从而达到起非法目的。关于Cross-site request forgery的介绍可以看维基科http://en.wikipedia.org/wiki/Csrf
解决办法简单来说就是:
首先,使用ASP.NET mvc的Anti-Forgery Tokens,让页面生成一个Hidden的input控件,这个隐藏的控件的值是一个随机的key,同时生成一个cookie,cookie的值和隐藏控件的值对应(下文代码中的Html.AntiForgeryToken()):
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Withdraw</h2> <% using (Html.BeginForm()) {%> <%= Html.AntiForgeryToken() %> <fieldset> <legend>Fields</legend> <p> <label for="Amount">Amount:</label> <%= Html.TextBox("Amount") %> </p> <p> <input type="submit" value="Withdraw" /> </p> </fieldset> <% } %> </asp:Content>
然后,在controler对应的Action方法上添加一个特别的Attribute[ValidateAntiForgeryToken],另外这个Action方法是一个Http Post方法。应用了Attribute[ValidateAntiForgeryToken],程序会检测Hiddden field的随机值和cookie是否一致,如果不一致,就会报AntiForgery validation failure的错误
using System.Web.Mvc; namespace MvcApplication1.Controllers { public class BankController : Controller { // GET: /Bank/Withdraw public ActionResult Withdraw() { return View(); } // POST: /Bank/Withdraw [AcceptVerbs(HttpVerbs.Post)] [ValidateAntiForgeryToken] public ActionResult Withdraw(decimal amount) { // Perform withdrawal return View(); } } }
个人认为这种攻击实施起来还是挺“麻烦”的,因为有种种限制(来自维基百科),当然如果网站忽略了对这种攻击的防范,那么制造这种攻击也是不难的:
Several things have to happen for cross-site request forgery to succeed:
- The attacker must target either a site that doesn't check the referrer header (which is common) or a victim with a browser or plugin that allows referer spoofing (which is rare).
- The attacker must find a form submission at the target site, or a URL that has side effects, that does something (e.g., transfers money, or changes the victim's e-mail address or password).
- The attacker must determine the right values for all the form's or URL's inputs; if any of them are required to be secret authentication values or IDs that the attacker can't guess, the attack will fail.
- The attacker must lure the victim to a Web page with malicious code while the victim is logged into the target site.