概述
眾所周知,ASP.Net MVC程序在瀏覽器運行時產生了標準的Html標簽,包括瀏覽器要發送的關鍵數據等內容都在Html內容里面,聽起來不錯,但是假如我們仿造類似的Html內容,更改里面關鍵數據,在瀏覽器運行起來會怎么樣呢?好下面我們就做這樣一個例子。
CSRF***例子
首先我們拿以前做好的person/edit作為例子
先看控制器代碼

//初始頁面
// GET: /Person/Edit/5
public ActionResult Edit(int id)
{
return View();
}
//修改方法
// POST: /Person/Edit/5
[HttpPost]
public ActionResult Edit(int id, Person person)
{
try
{
// 數據庫操作代碼
return RedirectToAction("Success",person);
}
catch
{
return View();
}
}

然后我們來看看視圖代碼

@model MvcApplication.Models.Person
@{
ViewBag.Title = "修改人員";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3>
修改人員</h3>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
<legend>人員信息</legend>
@Html.HiddenFor(model => model.ID)
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
<p>
<input type="submit" value="保存" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("返回列表", "Index")
</div>

運行起來看看

點擊保存后

可以看到,上面例子中的代碼都是正確的,運行都是正常的,下面我們來實現CSRF***。
實現CSRF***
打開記事本,寫入下面代碼
<body onload="document.getElementById('fm1').submit()">
<form id="fm1" action="http://localhost:5132/person/Edit/1001" method="post">
<input name="name" value="張三" />
<input name="age" value="21" />
</form>
</body>

另存為Html文件。
雙擊文件運行。。。

允許阻止的內容之后:

?????~~~不會吧,此時你可能已經傻了吧。。。這個就叫CSRF***。
什么是CSRF***
CSRF(Cross-site request forgery),中文名稱:跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF。
因為在ASP.NET程序中,我們的用戶信息都是存在與cookies里面的,此時在用戶自己來說,程序已經可以算是裸奔了。正因為如此,Web程序接受的正??蛻舳苏埱笠话銇碜杂脩舻狞c擊鏈接和表單提交等行為??墒菒阂?**者卻可以依靠腳本和瀏覽器的安全缺陷來劫持客戶端會話、偽造客戶端請求。***者盜用了你的身份,以你的名義發送惡意請求,以你名義發送郵件,發消息,盜取你的賬號,甚至于購買商品,虛擬貨幣轉賬......造成的問題包括:個人隱私泄露以及財產安全。這就是CSRF***。
CSRF漏洞的***一般分為站內和站外兩種類型:
CSRF站內類型的漏洞在一定程度上是由于程序員濫用$_REQUEST類變量造成的,一些敏感的操作本來是要求用戶從表單提交發起POST請求傳參給程序,但是由于使用了$_REQUEST等變量,程序也接收GET請求傳參,這樣就給***者使用CSRF***創造了條件,一般***者只要把預測好的請求參數放在站內一個貼子或者留言的圖片鏈接里,受害者瀏覽了這樣的頁面就會被強迫發起請求。
CSRF站外類型的漏洞其實就是傳統意義上的外部提交數據問題,一般程序員會考慮給一些留言評論等的表單加上水印以防止SPAM問題,但是為了用戶的體驗性,一些操作可能沒有做任何限制,所以***者可以先預測好請求的參數,在站外的Web頁面里編寫javascript腳本偽造文件請求或和自動提交的表單來實現GET、POST請求,用戶在會話狀態下點擊鏈接訪問站外的Web頁面,客戶端就被強迫發起請求。
瀏覽器的安全缺陷
現在的Web應用程序幾乎都是使用Cookie來識別用戶身份以及保存會話狀態,但是所有的瀏覽器在最初加入Cookie功能時并沒有考慮安全因素,從WEB頁面產生的文件請求都會帶上COOKIE
MVC中防止CSRF***
使用AntiForgeryToken令牌,在ASP.NET的核心中為我們提供了一個用來檢測和組織CSRF***的令牌。
只要在Html表單里面使用了@Html.AntiForgeryToken()就可以阻止CSRF***。

@model MvcApplication.Models.Person
@{
ViewBag.Title = "修改人員";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3>
修改人員</h3>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>人員信息</legend>
@Html.HiddenFor(model => model.ID)
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
<p>
<input type="submit" value="保存" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("返回列表", "Index")
</div>

相應的我們要在Controller中也要加入[ValidateAntiForgeryToken]過濾特性。
該特性表示檢測服務器請求是否被篡改。
注意:該特性只能用于post請求,get請求無效。

//修改方法
// POST: /Person/Edit/5
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult Edit(int id, Person person)
{
try
{
// 數據庫操作代碼
return RedirectToAction("Success",person);
}
catch
{
return View();
}
}

運行效果和上面的一樣

然后我們在運行剛才保存的Html文件看看

哈哈報錯了。。那就證明我們現在的阻止CSRF***是有效的。
使用Salt值加強保護
為了保證我們的AntiForgeryToken阻止在程序中唯一,更好的加密AntiForgeryToken,我們可以為AntiForgeryToken設置Salt值。
這樣,即使***者設法得到了令牌,但是如果Salt值不匹配也不能進行post操作。

//修改方法
// POST: /Person/Edit/5
[ValidateAntiForgeryToken(Salt = "aa")]
[HttpPost]
public ActionResult Edit(int id, Person person)
{
try
{
// 數據庫操作代碼
return RedirectToAction("Success",person);
}
catch
{
return View();
}
}

我們暫時不修改View代碼
運行看看

可以看到加入Salt值后即使是MVC程序本身的頁面都無法請求,更別說***者了,除非他能猜到我們的Salt值。
我們修改view代碼
@Html.AntiForgeryToken("aa")
繼續運行項目

可以看到在view中加入Salt值后,阻止就變的有目的性了。
總結
瀏覽器的會話安全特性 :
我們參照Set-Cookie的標準格式
Set-Cookie: <name>=<value>[; <name>=<value>] [; expires=<date>][; domain=<domain_name>] [; path=<some_path>][; secure][; HttpOnly]
瀏覽器支持的cookie實際上分為兩種形式:
一種是內存COOKIE,在沒有設定COOKIE值的expires參數,也就是沒有設置COOKIE的失效時間情況下,這個COOKIE在關閉瀏覽器后將失效,并且不會保存在本地。另外一種是本地保存COOKIE,也就是設置了expires參數,COOKIE的值指定了失效時間,那么這個COOKIE會保存在本地,關閉瀏覽器后再訪問網站,在COOKIE有效時間內所有的請求都會帶上這個本地保存COOKIE。
Internet Explorer有一個隱私報告功能,其實這是一個安全功能,它會阻擋所有的第三方COOKIE,比如A域Web頁面嵌入了B域的文件,客戶端瀏覽器訪問了A域的Web頁面后對B域所發起的文件請求所帶上的COOKIE會被IE攔截。除開文件請求情況,A域的Web頁面如果使用IFRAME幀包含B域的Web頁面,訪問A域的Web頁面后,B域的Web頁面里的所有請求包括文件請求帶上的COOKIE同樣會被IE攔截。不過Internet Explorer的這個安全功能有兩個特性,一是不會攔截內存COOKIE,二是在網站設置了P3P頭的情況下,會允許跨域訪問COOKIE,隱私報告功能就不會起作用了。
所以在Internet Explorer的這個安全特性的前提下,***者要進行站外的CSRF***使用文件請求來偽造GET請求的話,受害者必須在使用內存COOKIE也就是沒有保存登陸的會話狀態下才可能成功。而Firefox瀏覽器并沒有考慮使用這樣的功能,站外的CSRF***完全沒有限制。
關于Javascript劫持技術 :
近年來的web程序頻繁使用Ajax技術,JSON也開始取代XML做為AJAX的數據傳輸格式,JSON實際上就是一段javascript,大部分都是定義的數組格式。fortify公司的三位安全人員在2007年提出了Javascript劫持技術,這是一種針對JSON動態數據的***方式,實際上這也是一種變相的CSRF***。***者從站外調用一個script標簽包含站內的一個JSON動態數據接口,因為<script src=”>這種腳本標簽的文件請求會帶上COOKIE,用戶訪問后相當于被迫從站外發起了一個帶有身份認證COOKIE的GET請求,web程序馬上返回了用戶相關的JSON數據,***者就可以取得這些關鍵的JSON數據加以利用,整個過程相當于一個站外類型的CSRF***。
WEB應用中的JSON數據大部分使用在個人資料、好友列表等隱私功能里,這類數據一般是web蠕蟲最重要的傳播功能所需要的數據,而CSRF***結合Javascript劫持技術完全可以分析這類數據制作自動傳播的web蠕蟲,在一定情況下這種web蠕蟲比網站出現跨站腳本漏洞制作的web蠕蟲更具威脅性,幾乎不受網站架構的限制,因為***者利用的不是傳統的Web漏洞而是網站自身正常的功能,如果出現這類CSRF蠕蟲,對網站的打擊將是災難性的。
安全提醒 :
各個大型社區類網站必須警惕CSRF***和相關web蠕蟲的爆發,并且針對這類web***制定有效的應急措施。同建議程序員不要濫用$_REQUEST類變量,在必要的情況下給某些敏感的操作加上水印,考慮使用類似DISCUZ論壇的formhash技術提高***預測請求參數的難度,注意JSON數據接口的安全問題等。最后希望大家全面的考慮客戶端和服務端整體的安全,注意Internet Explorer等客戶端瀏覽器一些安全缺陷和安全特性,防止客戶端程序的安全問題影響整個Web應用程序。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。