安全在web領域是一個永遠都不會過期的話題,今天咱們就來看一看一些在開發ASP.NET MVC應用程序時一些值得咱們注意的安全問題。本篇主要包括如下幾個內容 :web
所謂認證,簡單的來講就是驗證一個用戶的身份。這取決於咱們開發的站點的類型,是否容許匿名訪問,是不是屬於管理員或者其它角色的用戶等等。也就是說咱們的整個程序或者某些功能是針對某些特定的用戶開發的,那麼咱們可能就要進行認證來肯定用戶的身份。須要注意的是,認證與受權是是徹底不同的概念,咱們要區別對待。打個比方,在ASP.NET MVC裏面容許某一類用戶訪問某個Action就是受權。windows
ASP.NET MVC中主要有兩種認證機制瀏覽器
從字面上咱們就能夠獲得一些信息,基於表單的認證提供給用戶一個表單能夠輸入用戶名和密碼,而後咱們能夠在咱們的程序中寫本身的邏輯去驗證這些信息。ASP.NET MVC爲Forms認證提供了不少支持,而且有很強自定義性。從經過表單登陸到用戶信息存儲在什麼地方,到怎麼樣去驗證這些用戶信息。Forms認證默認是依靠cookie技術實現的,一旦某個用戶登陸站點,那麼用戶所使用的這個瀏覽器就會獲得一個cookie而且在後面全部與這個站點的其它請求中都會將這個cookie包含在http的頭中。ASP.NET可以檢測到這個cookie,這個cookie中包含了用戶的認證信息,那麼後面就不須要再重複的認證用戶了。安全
Windows 認證也就是你們熟悉的集成身份認證,由於它使用了集成在Windows操做系統中的用戶組件來認證用戶。一旦某個用戶登陸到域中,Windows可以在應用程序中自動認證他們。Windows認證通常在企業局域網內比較經常使用,通常企業局域網中全部的用戶都須要用域身份來登陸,這個有點像單點登陸的體驗,一旦進入域中就能夠就能夠很方便的同時登陸域內的其它應用程序。服務器
首先咱們須要更改web.config中的authentication結點。cookie
這個配置信息很簡單,首先咱們要使用的authentication類型是Forms認證。經過loginUrl指定咱們認證用戶的頁面。這個Account Controller和 Login View還有一些容許用戶註冊的View都被ASP.NET MVC的internet模板默認實現了。咱們能夠垂手可得在在ASP.NET MVC中實現Forms認證。app
打開Visual Studio 2010 > New Project > Select ASP.NET MVC 4 Web Application 點擊確認。ide
而後選擇Internet Application點擊確認,Forms認證所須要的Controller 和View等等都會默認包含在咱們的項目裏面了。網站
Authorize不關注咱們如何認證用戶,咱們既能夠用Forms認證也能夠用Windows認證。Authorize會去檢測當前用戶是否有身份信息。若是咱們在Index上加上Authorize屬性那麼匿名用戶就不能訪問咱們的Index Action了。他們會被跳轉到Account/Login,也就是咱們上面在web.config中配置的loginUrl。
和Forms認證同樣,首先咱們須要更改一下web.config中的authentication結點。
而後一樣地,應用Authorize屬性到咱們的Index Action上。
咱們能夠將Authorize應用到一個單獨的Action上,也能夠應用到一個Controller上。當咱們在某一個Controller上應用Authorize屬性時,也就意味着這個Controller下全部的Action都必須是通過認證的用戶才容許訪問 。
若是使用IIS Express的話,咱們須要更改配置信息來啓用Windows認證。不然咱們就會獲得如下錯誤頁面。
咱們能夠到IIS Express的配置中去啓用Windows認證,打開Windows Explorer進入個人文檔> IIS Express > config > applicationhost.config。而後將windowsAuthentication enabled設置爲true。
而後咱們就能夠拿到一些用戶的信息。
受權容許咱們傳遞一些參數去設置規則,咱們能夠告訴Authroize屬性只有某些具體用戶才能夠訪問某個Action。
同時 ,咱們還能夠爲Authorize屬性指定 Roles。這些Roles默認匹配到咱們web服務器的Windows Group或者是域管理器裏面的用戶組。
在Forms認證中, ASP.NET爲咱們提供了一個角色管理器(role provider)咱們能夠經過它來方便和將咱們的角色信息存儲到SQL中,而且進行管理。咱們只須要點擊一個按鈕便可:
點擊上面這個按鈕以後,它會幫咱們運行ASP.NET configuration tool。這個站點只能在本地運行,咱們能夠在這個站點管理咱們的角色,這個站點默認使用的數據鏈接就是咱們配置在web.config中的鏈接字符串。
在web領域,有幾個比較常見的安全隱患,其中一個比較流行的就是跨站腳本攻擊。一些惡意的用戶經過一些手段讓咱們的站點加載一些惡意的腳本,那麼若是其它用戶訪問到這些腳本就有可能成爲受害者。除了腳本,包括active-x控件,甚至一些惡意的Html均可以成爲XSS的武器。XSS能夠作到哪裏事情 ?
簡單的說,咱們能夠經過XSS訪問用戶的我的信息以及身份信息。
這是一個簡單的錄入員工信息的頁面,咱們輸入一些html代碼而後保存頁面。ASP.NET默認會去檢測咱們的request,發現相似html代碼會直接拒絕咱們的請求。
固然,有些時候咱們須要容許用戶輸入html,那麼只要在咱們的Action上打上ValidateInput(false)便可。
這樣咱們就能夠成功的提交 咱們的請求了。
如上圖所示,這樣咱們又遇到了另一個問題。在ASP.NET MVC中razor默認會對全部輸出進行html編碼。這是ASP.NET MVC針對XSS攻擊的另外一道防火牆。經過爲屬性打上AllowHtml屬性,咱們能夠容許某一個屬性包含html的值,這樣咱們就能夠移除Action上的ValidateInput屬性。經過Html.Raw 咱們能夠將html輸出到客戶端。
若是咱們容許用戶輸入html的話,有些人可能會嘗試輸入一些腳本 (不要說你沒有想過在博客園輸入一些腳原本玩玩?)
幸運的是,Microsoft爲咱們提供了一個組件,咱們能夠經過nugget或者Library Package Manager Console( Visual Studio > Tools > Library Package Manager > Package Manager Console 輸入 Install-Package AntiXss回車 )
只須要簡單的一句話,就能夠移除全部的有害代碼,是否是感受又被Microsoft搞蠢了?
跨站請求僞造也是一種危險的主流攻擊。試想一下,某個用戶登陸到網站想修改一些我的信息,若是服務器端使用了Forms認證,那麼在這個用戶登陸以後就會獲得一個包含身份信息的cookie而且在後面全部這個站點下的請求中傳遞。固然這個並無錯,畢竟若是每次都去驗證用戶名和密碼是一次不小的開銷,驗證一次以後將登陸信息保存到cookie中,至少在用戶不關閉瀏覽器以前,咱們不用再從新去驗證用戶。
若是瀏覽器端依然保留着個人身份信息,那在我訪問其餘惡意的站點的時候。這些惡意的站點就能夠本身封裝一個表單並提交到咱們的服務器,雖然這個請求時惡意站點僞造的,可是由於它帶有用戶的身份,因此服務器是會正常處理的。小到更改用戶資料,大到轉走用戶的帳戶餘額都成爲可能。
因此咱們在處理請求的時候,不只僅須要驗證用戶身份信息,還須要確保發送數據的表單是由咱們服務器產生的。這樣就能夠避免其餘惡意用戶僞造表單發送數據。
這裏有一段很常見的代碼,經過Edit Action來編輯用戶信息。咱們已經爲Edit 打上了Authorize屬性,也就是說用戶是須要登陸才能訪問這個Action的。從普通開發的角度來看,這個程序是不會有什麼問題的,咱們首先經過正常渠道添加了一個用戶。
接下來,很雷很雷的事情發生了。你收到一封郵件說你中獎了,給了你一個連接,或者在某個網站上自己就嵌入了一些惡意代碼,而你不幸手一抖,就點了。接下來結果有多是這樣滴。
你的數據很輕鬆就被篡改了。若是帳號是有餘額的,你就哭吧。來看看這個頁面 是如何實現的。
很是的簡單,咱們只須要將form的action指向實際的action就能夠了。這個頁面一旦被加載,這個表單就會自動提交,那咱們的數據就被黑了,一切都是那麼的簡單。
ASP.NET MVC 爲咱們提供了Html.AntiForgeryToken() 方法,咱們只須要在form中添加這句話。MVC 會爲咱們生成一個惟一標識放在form中的一個隱藏域中,該標識還會被存放到cookie中在客戶端和服務器的請求中傳輸。另外咱們要作的就是爲咱們的Action打上ValidateAntiForgeryToken的屬性。
若是請求不包含這個cookie,那服務器就會拒絕這個請求,從而避免CSRF的攻擊。
原文:http://www.codeproject.com/Articles/654846/Security-In-ASP-NET-MVC
本篇是根據上面的文章按照個人理解翻譯的。
今天的故事就講到這裏,謝謝你們的收看!