文章目錄
- 1. 理解潛在的威脅
- 2. 安全編程原則
- 3. Gatekeeper
- 1. 驗證
- 2. 授權
- 3. 機密性和完整性
設計一個適當的安全性原則是所有分布式應用程式的關鍵區段之一,對於暴露在網際網路上的大型 Web 應用程式尤為如此。
安全是 Web 應用程式的重要組成部分,開發伊始就應被納入規劃。通常採用如下幾種機制:使用者驗證、授權、禁止訪問敏感資源、保護伺服器上儲存的資料、保護網路上傳輸的資料。
ASP.NET 用內建的一個提供基本安全功能的底層架構來滿足這一需求。ASP.NET 的安全架構套件括了使用者驗證和授權的類,也提供了在應用程式中處理已驗證使用者的類。它還有一組系統管理使用者和角色的進階模型,允許編程訪問或使用內建管理工具來進行管理。此外,.NET Framework 本身也提供了一系列基類,用來保證加密和數位簽章過程中資料的機密性和完整性。
為何建立安全軟體?
.NET 和 ASP.NET 提供的安全架構非常強大,但必須將若干基本原則銘記於心,並在正確場合下正確使用它們。在很多項目中,安全問題被認為是事後考慮的事情,所以系統架構師和開發人員早期不會考慮它們。但如果在項目開始(架構和設計時期)不將安全問題牢記於心,如何能在合適的時候正確的使用 .NET Framework 提供的所有安全功能呢?
因此,在開發最初就考慮安全性問題是非常重要的,這樣才可能在建立架構和設計時,對安全問題作出正確的決策。
1. 理解潛在的威脅
建立安全的架構和設計需要你對程式的運行環境有非常深入的瞭解。誰會訪問你的程式?哪兒可能會成為攻擊點?因此,安全首先基於你對周圍環境因素的充分瞭解,比如使用者、登入點和潛在的可能攻擊點的威脅。
這也是威脅模型在現代軟體開發流程中日益重要的原因。威脅模型採用結構化的方法剖析器環境中的威脅,對這些威脅進行評級,然後基於這些威脅選取減緩它們的技術。這樣,對安全技術(比如驗證或 SSL 加密)的決策總是建立在現實依據(威脅自身)的基礎上的。
威脅模型之所以重要,還有另外一個原因。不是所有的潛在威脅都可以使用驗證和授權機制等技術來減輕。換言之,一些潛在的威脅是無法用技術手段解決的。比如,線上銀行可以使用 SSL 來保證銀行網站的安全傳輸,但使用者如何才能知道他們訪問的是銀行網站,而不是駭客偽裝過的網站呢?目前唯一可行的途徑是通過查看用來建立 SSL 通道的認證來確定網站。
威脅模型是一個很大的主題,有一本書對於專案經理和架構師非常重要:Michael Howard 和 Steve Lipner 著的 Security Development Lifecyle。這本書重點講述了如何讓安全成為軟體開發聲明周期的一部分,從開始的計劃階段到架構、開發、測試和維護。它總結了微軟的專案管理是如何讓安全以平滑、實用的方式成為整個項目的一部分。
2. 安全編程原則
僅有安全的架構和設計不會使你對程式安全高枕無憂,它只是其中重要因素之一。你還必須寫出安全的代碼。具體到 Web 程式,應當將如下原則牢記於心:
- 絕不相信使用者的輸入:要假定每一個使用者都是惡意的,除非你能證明他不是。使用者輸入的資訊總是要強制進行驗證;只根據有效值去驗證;你不可能想得出所有的無效值,它總會比你想象的更多。
- 絕對不要使用字串串連符來建立 SQL 陳述式:應總是使用參數化的語句來確保程式不會被 SQL 注入。
- 絕對不要將沒有經過驗證和編碼的使用者輸入直接顯示在網頁上:使用者可能會輸入一些程式碼片段(攻擊指令碼)。在輸出頁面資料之前,一定要使用 HttpUtility.HtmlEncode() 來轉義特殊字元,或使用 Web 控制項自動執行編碼工作。
- 絕對不要將敏感性資料、關鍵業務資料以及影響企業內部決策的資料以隱藏欄位的形式儲存在網頁上:只要查看網頁的原始碼、修改它並將其儲存到本地檔案中就可以輕易的修改隱藏欄位。攻擊者只要將本地的網頁提交到伺服器就可以實現攻擊。
- 絕對不要將敏感性資料或者關鍵業務資料存放區在檢視狀態:檢視狀態是頁面上另一個隱藏地區,它也可以輕易的被解碼查看。檢視狀態加密雖然能協助保護在一段很短的時間裡有用的資訊,但如果攻擊者擁有充分的時間、資源和動機,即使加密的資訊也可以被破解。
- 使用基本驗證或者 ASP.NET 的表單驗證時啟用 SSL:關於 SSL 後續系列會詳細介紹。
- 保護 cookie:當使用表單驗證時,一定要保護用於驗證的 cookie,並儘可能的設定逾時時間為更短。
- 使用 SSL:通常,Web 程式需要處理敏感性資料就應該使用 SSL 來保障整個網站的安全,同時不要忘記使用 SSL 來保護本不是由應用程式直接管理的圖片目錄或存放其他檔案的目錄。
以上只是基本的重要原則,具體到應用程式,你需要建立威脅模型來產生潛在威脅的完整列表。另外,如果你忘了上述任何一個指導原則,其他的安全特性就形同虛設了。系統的安全強度取決於它最薄弱的環節!
3. Gatekeeper
一個增強應用程式安全性的好方法是部署很多的組件來加強安全性。Gatekeeper(安全守衛)是一個概念模式,它將流水線模型應用到系統安全架構中。Gatekeeper 假定一個安全的程式應該部署更多的安全機制,而不僅僅是必需的安全機制。
ASP.NET 的程式架構也使用了這種機制。ASP.NET 包含有若干 Gatekeeper,每一個都被用來增強一些安全條件。在後續的文章中,你將會瞭解 ASP.NET Framework 包含的各種 Gatekeeper 以及它們各自的責任。
理解安全層級
對於主流的 Web 應用程式來講,實現安全的基本任務通常是相同的:
- 驗證:驗證會問這樣的問題:這是誰?它確定誰在另一端使用你的程式。
- 授權:授權會問這樣的問題:你可以執行什麼樣的操作?你可以訪問什麼資源?你的操作許可權是什嗎?
- 機密性:當使用者使用程式時,你必須保證沒人可以查看這個使用者正在處理的敏感性資料。因此,你需要對用戶端的瀏覽器和 Web 服務器之間的通道進行加密。你還可能必須加密儲存在背景資料,甚至資料庫管理員或網站託管公司的員工都不能查看這些資料。
- 完整性:你必須保證資料在用戶端和伺服器端傳輸的過程中沒有被非授權者修改過。數位簽章提供了一個減輕這種威脅的途徑。
ASP.NET 包含了一個用來執行驗證和授權的基本架構。.NET Framework 基底類別庫包含一些位於 System.Security 命名空間中的類,用來加密資料並對資料簽名。此外,用戶端和伺服器之間傳送的資料,SSL 是保證資料機密性和完整性的標準化方式。
1. 驗證
驗證是發現一個使用者的身份並保證此身份真實性的過程。在 ASP.NET 應用程式中,有以下 4 個驗證系統:
- Windows 驗證
- 表單驗證
- Passport 驗證
- 自訂驗證
在每種驗證系統中,使用者都必須在登入時提供一些證明資訊。系統根據驗證類型的不同而採取不同的方式來跟蹤使用者身份。比如,Windows 作業系統使用一個 96 位的 SID(安全性識別碼)確定每一個登入使用者;表單驗證中,使用者被賦予一個儲存在 cookie 裡面的驗證票據,其中包含了各種加密過的資料。
所有的驗證都允許程式在處理每次請求時識別使用者身份。它可以滿足個人化和定製化的需要,身份資訊在網頁上展示使用者特定的資訊,或改變網站的外觀。但驗證本身並不足以限制使用者被允許執行的任務。
2. 授權
授權是決定指派給已驗證使用者的權力和限制的過程。授權是以這個使用者所屬的角色或者組為基礎的,而不是這個使用者是誰。很多情況下,基於角色的授權機制是非常可取的,實施起來非常容易。例如,角色可能被分為經理、管理員、遊客、銷售人員、客戶等等。
Web 應用程式在不同層級上進行不同類型的授權。比如在最進階別,代碼可以檢查使用者的身份並決定某個特定的操作是否繼續。在較低層級上,你可以配置 ASP.NET 禁止使用者或角色訪問特定的目錄和網頁。在更低層的層級上,當執行不同的任務(串連資料庫、開啟檔案、寫入事件記錄等),Windows 作業系統會檢查執行這些代碼的使用者的許可權。
大多數情況下,你不需要使用最底層層級,因為代碼總是以一個固定帳號執行。在 IIS 7.x 中,是 Network Service 帳號。
3. 機密性和完整性
機密性:資料在網路傳輸過程中或在資料庫之類的存放裝置中儲存時不會被未經授權的使用者查看。
完整性:資料在網路傳輸過程中或在資料庫之類的存放裝置中儲存時沒有人能修改它。
這兩者以加密為基礎。加密是將資料不規則化以使其他使用者無法閱讀的過程。在 ASP.NET 中,加密功能對驗證、授權、身份類比來講是完全獨立的。可以一起使用,也可以單獨使用加密功能。
- 保護資料轉送:SSL 是解決此問題的行業標準。SSL 也通過數位簽章來保證資料的完整性。但 SSL 不是由 ASP.NET 實現的,而是 IIS 提供的一個功能。無論是否使用 SSL,你的頁面程式(或 Web 服務)代碼都是一樣的。
- 保護永久資訊:你應該在儲存資料之前使用 .NET 提供的加密類對它們進行手工加密。
另外,.NET 加密類可以用在任何類型的 .NET 程式中,並非只用於 ASP.NET 或 ASP.NET MVC 等網路應用程式中,這點不要混淆。
互相協作
Web 應用程式中,驗證、授權、身份類比是如何互相協作的呢?
當使用者首次訪問網站,他們是匿名的,你並不關心他們是誰,他們可以訪問任何網頁。但當使用者請求一個匿名使用者無法訪問的頁面時,會發生以下幾個步驟:
- 因為無法得知使用者身份,所以會要求使用者登入(自訂登入網頁或者登入的彈出框等),這取決於你使用何種類型的驗證方式。
- 使用者提供身份,你的程式來檢驗(使用表單驗證) 或者 由 IIS 自動檢驗(使用 Windows 驗證)。
- 通過了驗證,使用者被賦予頁面的存取權限。否則,會被提示再次登入或者導航至某個“拒絕訪問”頁面。
如果是訪問了一個只允許特定使用者或特定角色才能訪問的頁面,那麼在上述過程中,在身分識別驗證通過後,還需進行角色的驗證等。