CSRF(Cross-site request forgery)跨站請求偽造,也被稱為“One Click Attack”或者Session Riding,通常縮寫為CSRF或者XSRF,是一種對網站的惡意利用。盡管聽起來像跨站腳本(XSS),但它與XSS非常不同,XSS利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF攻擊往往不大流行(因此對其進行防范的資源也相當稀少)和難以防范,所以被認為比XSS更具危險性。(百度百科)
一個場景
加入有這樣一個發布公司新聞的頁面
@{ ViewBag.Title = "News"; } <h2>News</h2> @using (Html.BeginForm("PostNews", "News", FormMethod.Post)) { <input type="text" name="content" id="content" /> <input type="submit" value="Submit" /> }
控制器
public class NewsController : Controller { // GET: News [HttpPost] public ActionResult PostNews() { ViewBag.content = Request.Form["content"]; return View(); } [HttpGet] public ActionResult News() { return View(); } }
提交成功
此時提供給了跨站攻擊的漏洞,CSRF一般依賴幾個條件
(1)攻擊者知道該目標站點。
(2)攻擊者的目標站點具有持久化授權cookie或者受害者具有當前會話cookie
(3)目標站點沒有對用戶在網站行為的第二授權。
比如我們現在知道發布新聞的地址:http://localhost:28401/News/PostNews
我們下面新建一個頁面test.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form action="http://localhost:28401/News/PostNews" method="post"> <input type="hidden" name="content" value="你們公司網站被黑了" /> <input type="submit" name="name" value="提交" /> </form> </body> </html>
發起攻擊
這樣在公司站點的新聞列表就被篡改了。作為安全性考慮,這種情況肯定不會讓它發生的,如果涉及到公司利益,那就損失大了。
MVC中如何防范?
還好,mvc中通過在頁面上使用 Html.AntiForgeryToken()配合在對應的Action上增加[ValidateAntiForgeryToken]特性來防止跨站攻擊。
修改上面提交代碼
@using (Html.BeginForm("PostNews", "News", FormMethod.Post)) { @Html.AntiForgeryToken() <input type="text" name="content" id="content" /> <input type="submit" value="Submit" /> }
[HttpPost] [ValidateAntiForgeryToken] public ActionResult PostNews() { ViewBag.content = Request.Form["content"]; return View(); }
我們這里再次使用test.html進行提交
我們看一下Html.AntiForgeryToken()會為當前請求,生成一個名為__RequestVerificationToken的cookie,還有一個名為__RequestVerificationToken的隱藏域。
為了驗證一個來自form post請求,還需要在目標action上增加[ValidateAntiForgeryToken]特性,它是一個驗證過濾器,它主要檢查
(1)請求的是否包含一個約定的AntiForgery名的cookie
(2)請求是否有一個Request.Form["約定的AntiForgery名"],約定的AntiForgery名的cookie和Request.Form值是否匹配
總結
在asp.net mvc中,需要加上Html.AntiForgeryToken()防止CSRF攻擊,在使用ajax進行post請求的時候,需要獲取到名為__RequestVerificationToken的隱藏域的值進行一起提交。
參考