網(wǎng)絡攻擊技術——Broken authentication
1.1.1 摘要
在日常的互聯(lián)網(wǎng)生活當中,我們幾乎都離不開用戶驗證登陸功能,例如:登陸微博,Gmail,博客園,Stackoverflow等網(wǎng)站,這給我們帶來了一些不便,就是要管理一堆的用戶名和密碼,也許有人會說現(xiàn)在很多網(wǎng)站都提供授權驗證登陸功能,其中使用最廣泛的是OAuth驗證機制;在某些情況下,例如一些論壇網(wǎng)站提供微博賬戶登陸功能,它的實現(xiàn)的卻方便了用戶,因為它為用戶開放服務和重用現(xiàn)有的賬戶,把認證過程轉(zhuǎn)給外部服務。
但是作為開發(fā)者的我們還必須考慮到一些用戶會采用內(nèi)部應用程序授權,所以我們還需要提供內(nèi)部用戶驗證登陸功能。
本文目錄
1.1.2 正文
定義:
在應用程序中,如果驗證和會話(Session)管理的功能沒有正確實現(xiàn)時,導致攻擊者可以竊取用戶密碼,會話令牌或利用其他漏洞來偽裝成其他用戶身份。
剖析破壞驗證:
在ASP.NET中,會話狀態(tài)(Session state):是通過在內(nèi)存中以字典或哈希表的數(shù)據(jù)結構來存儲用戶的會話;例如:以哈希表(Key/Value)形式來存儲,那么根據(jù)Key值(SessionId)檢索指定的Value值(Session)的時間復雜度是O(1)。
我們知道HTTP是無狀態(tài)協(xié)議,簡而言之,由于Web服務器不會保留以前請求過程中所使用的變量值和任何信息,所以它會把每個頁面請求都認為是獨立的;但我們知道當用戶成功登陸之后,再訪問其他頁面時是無需重新登陸就可以訪問授權頁面了,這是由于在Web服務器和瀏覽器之間維持著一個Session state。
ASP.NET 會話狀態(tài)(Session state)將來自限定時間范圍內(nèi)的同一瀏覽器的請求標識為一個會話,并提供用于在該會話持續(xù)期間內(nèi)保留變量值的方法。默認情況下,將為所有 ASP.NET 應用程序啟用 ASP.NET 會話狀態(tài)。
請求持久化的實現(xiàn):當會話開始時,ASP.NET應用程序通過向客戶端提供一個唯一的密鑰(SessionId)來管理會話狀態(tài)(Session state),這個密鑰(SessionId)存儲在客戶端向服務器發(fā)送的每個HTTP請求的cookie中;然后,服務器可以從cookie中讀取密鑰(SessionId),并重新存儲到服務器的會話狀態(tài)。
現(xiàn)在我們使用Fiddler查看HTTP請求中的數(shù)據(jù)如下:
圖1 HTTP請求
我們看到在HTTP請求中,Header的Cookie里包含了SessionId值,然后Web服務器就可以獲取到Cookie中的SessionId值,由于每個會話都擁有一個唯一的SessionId值,所以Web服務根據(jù)SessionId來識別不同的會話。
接下來讓我們通過具體的例子說明白吧!
現(xiàn)在讓我們通過一個簡單的登錄頁面來說明會話(Session)的原理:
首先我們設計一個簡單的登界面。
圖2登陸界面
當?shù)顷懗晒χ螅@示信息和跳轉(zhuǎn)頁面。(注意:登陸和提示在同一個頁面)
圖3登陸成功
/// <summary> /// Handles the Click event of the btnLogin control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> /// instance containing the event data.</param> protected void btnLogin_Click(object sender, EventArgs e) { lblUsername.Visible = false; lblpassword.Visible = false; txtPassword.Visible = false; txtUsername.Visible = false; btnLogin.Visible = false; //// After successful authentication, save username into session. Session["Username"] = txtUsername.Text; //// Shows message and redirect link. lblMsg.Visible = true; hlpage.Visible = true; }
圖4跳轉(zhuǎn)頁面
上面的示例代碼中,我們并沒有給出具體的驗證實現(xiàn),由于我們關注的是用戶驗證成功之后,程序把用戶信息存儲到Session中,當頁面發(fā)生跳轉(zhuǎn)時,通過Session獲取用戶信息。
現(xiàn)在我們在cookies頁面中,查看當前SessionId的值如下:
圖5會話id
由于數(shù)據(jù)通過會話狀組織起來,會話是由客戶端瀏覽器指定,并且通過瀏覽器的cookie持久化存儲,現(xiàn)在我們把以上Url復制到其他瀏覽器的地址欄中。
圖6會話
如上圖所示,在Chrome瀏覽器中不能獲取我們之前保存在Session中的Username,而且我們查看Chrome中的SessionId值如下:
圖7會話id
現(xiàn)在我們知道Session可以通過Cookie持久化存儲,但由于不同的瀏覽器都會保存各自的Cookie,導致Session無法跨瀏覽器。
現(xiàn)在我們不把Session保存在Cookie中,而是通過Url直接傳遞到服務器中,這就可以實現(xiàn)Session跨瀏覽器,接下來讓我們看一下ASP.NET中的實現(xiàn)吧!
<system.web> <!--Don't use cookies to persist session--> <sessionState cookieless="true" /> </system.web>
我們在WebConfig中設置cookieless="true",當再次運行Logon頁面時,我們發(fā)現(xiàn)Url中嵌入了一個字符串,這是由于cookieless="true"不把Session保存在Cookie中,而是通過在Url中嵌入SessionId進行傳遞。
圖8 Url傳遞SessionId
當我們輸入用戶名和密碼登陸后,顯示用戶登陸成功如下所示:
圖9 Url傳遞SessionId
接著我們點擊鏈接頁面跳轉(zhuǎn)到Redirect,我們發(fā)現(xiàn)SessionId和剛開始登陸時候使用的是同一個,這樣Web服務器就可以根據(jù)SessionId獲取會話信息。
圖10 Url傳遞SessionId
由于我們在webconfig中設置cookieless="true",這樣就實現(xiàn)了跨瀏覽器訪問授權頁面,但這也存在一個嚴重的安全問題――Session劫持。
假如我們都在頁面的Url中嵌入SessionId,一旦SessionId被攻擊者獲取他們就無需再登錄就可以訪問授權頁面了,這對用戶來說可是一場災難。
也許有人想如果在Url中嵌入SessionId冒著很大的風險,還不如直接把SessionId存儲在Cookie中;但是使用Cookie持久化也可能發(fā)生Session劫持,由于Cookie是一個Key/Value的集合,攻擊者可以通過類似XSS或其他攻擊獲取用戶的Cookie。
幸運的是ASP.NET中把所有的Cookie都標記為HttpOnly,這使得攻擊者無法通過客戶端腳本(如document.cookie)獲取瀏覽器的Cookie,例如:通過跨站腳本(XSS, Cross Site Script)漏洞進行攻擊。
HttpOnly是Set-Cookies中一個附加標記,如果在HTTP響應頭中包含HttpOnly標志(可選),那么將不能通過客戶端腳本訪問Cookie(再次瀏覽器是否支持此標志)。因此,即使存在跨站點腳本(XSS)漏洞,也不能訪問瀏覽器的Cookie。(HttpOnly是由微軟在2000年IE6 Sp1中率先發(fā)明并予以支持的)
從表中我們可以看出,目前主流的瀏覽器,除了Android之外,幾乎都無一例外對HttpOnly屬性予以了支持。
|
Browser |
Version |
Prevents Reads |
Prevents Writes |
|
Microsoft Internet Explorer |
10 |
Yes |
Yes |
|
Microsoft Internet Explorer |
9 |
Yes |
Yes |
|
Microsoft Internet Explorer |
8 |
Yes |
Yes |
|
Microsoft Internet Explorer |
7 |
Yes |
Yes |
|
Microsoft Internet Explorer |
6 (SP1) |
Yes |
No |
|
Microsoft Internet Explorer |
6 (fully patched) |
Yes |
Unknown |
|
Mozilla Firefox |
3.0.0.6+ |
Yes |
Yes |
|
Netscape Navigator |
9.0b3 |
Yes |
Yes |
|
Opera |
9.23 |
No |
No |
|
Opera |
9.5 |
Yes |
No |
|
Opera |
11 |
Yes |
Unknown |
|
Safari |
3 |
No |
No |
|
Safari |
5 |
Yes |
Yes |
|
iPhone (Safari) |
iOS 4 |
Yes |
Yes |
|
Google's Chrome |
Beta (initial public release) |
Yes |
No |
|
Google's Chrome |
12 |
Yes |
Yes |
|
Android |
Android 2.3 |
Unknown |
Unknown |
ASP.NET membership和role providers的用戶驗證功能
現(xiàn)在,我們對驗證破壞和會話管理有了初步的了解,接下來我們使用ASP.NET中提供的membership和role providers來解決用戶驗證問題吧!
.NET Framkework 2.0中微軟提出了提供者模式(Provider)而且membership和role provider也是基于該模式實現(xiàn)的,在NET2.0或之后的版本,已經(jīng)提供解決涉及到用戶身份驗證和訪問權限管理方法,它們都是提供者模式的。 而且常用功能如帳戶的創(chuàng)建、驗證、授權和密碼提醒等,這方便了開發(fā)者無需從頭開始創(chuàng)建,減少引入不安全的代碼。
相信許多人都實現(xiàn)過頁面登陸功能,這個看似簡單的功能,但實際實現(xiàn)起來時很復雜的,由于.NET中提供LoginView控件已經(jīng)實現(xiàn)了功能,它整合了用戶身份驗證和訪問管理。
除了LoginView控件之外,我們還可以在Visual Studio工具箱中找到其他類似的控件。這些控件都集成了一些常用的功能(如:驗證登陸,登陸狀態(tài)和修改密碼等),這樣我們就無需編寫重復的代碼就可以很好的實現(xiàn)用戶驗證登陸功能。
圖11 Login控件
會話有效期
由于會話(Session)是有生命周期的,在發(fā)生會話劫持時,如果該會話已經(jīng)過期,那么就可以降低被劫持的風險,我們是否應該把會話的生命周期設置的很短呢?回答是否定的,如果會話很快就過期,那么用戶就要不斷重新登錄才能訪問授權頁面,這樣的用戶體驗效果是很差;所以我們必須在衡量風險和體驗效果前提下設置timeout值。
默認情況下,ASP.NET中在不活動情況下Session的timeout值為30分鐘。我們可以通過在web.config中設置Session的timeout屬性來修改過期時間,這里我們把Session過期時間設置為10分鐘,具體實現(xiàn)如下:
<system.web> <!--Setting session expiration date--> <sessionState timeout="10" /> </system.web>
前面我們在程序中設置了會話過期時間,當然用戶也可以通過手動Log out使會話過期。
加密
應該牢記在心充足的數(shù)據(jù)加密可以確保用戶身份驗證數(shù)據(jù)安全性,實現(xiàn)安全認證憑據(jù)披露的影響明顯和加密的緩解需要發(fā)生在兩個關鍵層的認證過程:
1.通過存儲持久數(shù)據(jù)層的加密(關于數(shù)據(jù)加密請參看這里和這里)。
2.正確使用 SSL。
Cookie一個不太常被使用的屬性是Secure. 這個屬性啟用時,瀏覽器僅僅會在HTTPS請求中向服務端發(fā)送Cookie內(nèi)容。如果你的應用中有一處非常敏感的業(yè)務,比如登錄或者付款,需要使用HTTPS來保證內(nèi)容的傳輸安全;而在用戶成功獲得授權之后,獲得的客戶端身份Cookie如果沒有設置為Secure,那么很有可能會被非HTTPS頁面中拿到,從而造成重要的身份泄露。所以,在我們的Web站點中,如果使用了SSL,那么我們需要仔細檢查在SSL的請求中返回的Cookie值,是否指定了Secure屬性。
1.1.3 總結
本文介紹了驗證破壞和會話劫持攻擊,通過具體的例子介紹了會話(Session)在瀏覽器中的工作原理,通過Cookie來保持身份認證的服務端狀態(tài),這種保持可能是基于會話(Session)的,也可以是通過在Url中嵌入SessinId持久化。
接著我們介紹了.NET中用戶驗證功能——ASP.NET membership和role providers的用戶驗證功能。
最后,介紹通過設置合適的會話有效期和加密驗證信息可以更好的確保用戶驗證的安全性。
http://msdn.microsoft.com/en-us/library/ms178581(v=vs.90).aspx
http://msdn.microsoft.com/en-us/library/a28ctsa5.aspx
http://www.infoq.com/cn/articles/cookie-security
系列博客導航
|
|
關于作者:[作者]:
JK_Rush從事.NET開發(fā)和熱衷于開源高性能系統(tǒng)設計,通過博文交流和分享經(jīng)驗,歡迎轉(zhuǎn)載,請保留原文地址,謝謝。 |

1.1.1 摘要 在日常的互聯(lián)網(wǎng)生活當中,我們幾乎都離不開用戶驗證登陸功能,例如:登陸微博,Gmail,博客園,Stackoverflow等網(wǎng)站,這給我們帶來了一些不便,就是要管理一堆的用戶名和密碼...











浙公網(wǎng)安備 33010602011771號