ASP.NET安全

騰飛(Jesse)發表於2013-10-23

ASP.NET 安全

概述

  安全在web領域是一個永遠都不會過時的話題,今天我們就來看一看一些在開發ASP.NET MVC應用程式時一些值得我們注意的安全問題。本篇主要包括以下幾個內容 :

  1. 認證
  2. 授權
  3. XSS跨站指令碼攻擊
  4. 跨站請求偽造

認證

  所謂認證,簡單的來說就是驗證一個使用者的身份。這取決於我們開發的站點的型別,是否允許匿名訪問,是否是屬於管理員或者其它角色的使用者等等。也就是說我們的整個程式或者某些功能是針對某些特定的使用者開發的,那麼我們可能就要進行認證來確定使用者的身份。需要注意的是,認證與授權是是完全不一樣的概念,我們要區別對待。打個比方,在ASP.NET MVC裡面允許某一類使用者訪問某個Action就是授權。

ASP.NET MVC中主要有兩種認證機制

  1. Forms 認證
  2. Windows 認證

Forms 認證

  從字面上我們就可以得到一些資訊,基於表單的認證提供給使用者一個表單可以輸入使用者名稱和密碼,然後我們可以在我們的程式中寫自己的邏輯去驗證這些資訊。ASP.NET MVC為Forms認證提供了很多支援,並且有很強自定義性。從通過表單登入到使用者資訊儲存在什麼地方,到怎麼樣去驗證這些使用者資訊。Forms認證預設是依靠cookie技術實現的,一旦某個使用者登入站點,那麼使用者所使用的這個瀏覽器就會得到一個cookie並且在後面所有與這個站點的其它請求中都會將這個cookie包含在http的頭中。ASP.NET能夠檢測到這個cookie,這個cookie中包含了使用者的認證資訊,那麼後面就不需要再重複的認證使用者了。

Windows認證

  Windows 認證也就是大家熟悉的整合身份認證,因為它使用了整合在Windows作業系統中的使用者元件來認證使用者。一旦某個使用者登入到域中,Windows能夠在應用程式中自動認證他們。Windows認證一般在企業區域網內比較常用,一般企業區域網中所有的使用者都需要用域身份來登入,這個有點像單點登入的體驗,一旦進入域中就可以就可以很方便的同時登入域內的其它應用程式。

配置Forms認證

  首先我們需要更改web.config中的authentication結點。

 

  這個配置資訊很簡單,首先我們要使用的authentication型別是Forms認證。通過loginUrl指定我們認證使用者的頁面。這個Account Controller和 Login View還有一些允許使用者註冊的View都被ASP.NET MVC的internet模板預設實現了。我們可以輕而易舉在在ASP.NET MVC中實現Forms認證。

開啟Visual Studio 2010 > New Project > Select ASP.NET MVC 4 Web Application 點選確認。

 

然後選擇Internet Application點選確認,Forms認證所需要的Controller 和View等等都會預設包含在我們的專案裡面了。

 

Authorize 屬性

  Authorize不關注我們如何認證使用者,我們既可以用Forms認證也可以用Windows認證。Authorize會去檢測當前使用者是否有身份資訊。如果我們在Index上加上Authorize屬性那麼匿名使用者就不能訪問我們的Index Action了。他們會被跳轉到Account/Login,也就是我們上面在web.config中配置的loginUrl。

如何配置Windows認證

  和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中的連線字串。

 

 

XSS跨站指令碼攻擊

在web領域,有幾個比較常見的安全隱患,其中一個比較流行的就是跨站指令碼攻擊。一些惡意的使用者通過一些手段讓我們的站點載入一些惡意的指令碼,那麼如果其它使用者訪問到這些指令碼就有可能成為受害者。除了指令碼,包括active-x控制元件,甚至一些惡意的Html都可以成為XSS的武器。XSS可以做到哪裡事情 ?

  1. 竊取cookie
  2. 更改使用者設定
  3. 下載惡意軟體
  4. 更改內容
  5. 賬戶劫持

簡單的說,我們可以通過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輸出到客戶端。

 

 

 

Anti XSS library

如果我們允許使用者輸入html的話,有些人可能會嘗試輸入一些指令碼 (不要說你沒有想過在部落格園輸入一些指令碼來玩玩?)

 

幸運的是,Microsoft為我們提供了一個元件,我們可以通過nugget或者Library Package Manager Console( Visual Studio > Tools > Library Package Manager > Package Manager Console 輸入 Install-Package AntiXss回車 )

 

只需要簡單的一句話,就可以移除所有的有害程式碼,是不是感覺又被Microsoft搞蠢了?

CSRF跨站請求偽造

  跨站請求偽造也是一種危險的主流攻擊。試想一下,某個使用者登入到網站想修改一些個人資訊,如果伺服器端使用了Forms認證,那麼在這個使用者登入之後就會得到一個包含身份資訊的cookie並且在後面所有這個站點下的請求中傳遞。當然這個並沒有錯,畢竟如果每次都去驗證使用者名稱和密碼是一次不小的開銷,驗證一次之後將登入資訊儲存到cookie中,至少在使用者不關閉瀏覽器之前,我們不用再重新去驗證使用者。

安全隱患在哪裡?

  如果瀏覽器端依然保留著我的身份資訊,那在我訪問其他惡意的站點的時候。這些惡意的站點就可以自己封裝一個表單並提交到我們的伺服器,雖然這個請求時惡意站點偽造的,但是因為它帶有使用者的身份,所以伺服器是會正常處理的。小到更改使用者資料,大到轉走使用者的賬戶餘額都成為可能。

  所以我們在處理請求的時候,不僅僅需要驗證使用者身份資訊,還需要確保傳送資料的表單是由我們伺服器產生的。這樣就可以避免其他惡意使用者偽造表單傳送資料。

 

CSRF示例

 

  這裡有一段很常見的程式碼,通過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

本篇是根據上面的文章按照我的理解翻譯的。

今天的故事就講到這裡,謝謝大家的收看!

相關文章