2016年5月28日 星期六

《建立無懈可擊安全 Web 系統 (第二版)》筆記

一、類別庫與安全類別

1.System.Security(資訊處理和其他安全認證):

(1)檔案系統控制:FileIOPermissionAccess

  • Read:只有讀取檔案內容的許可權。
  • Write:只有刪除與改寫檔案內容的許可權。
  • Append:僅有檔案結尾寫入的能力,不能讀取。
  • PathDiscovery:對路徑本身資訊的存取權限。不授與對路徑所指的檔案或資料夾的存取權限。

(2)記錄檔存取控制:EventLogPermission
SecurityAction.PermitOnly:確保WriteToLog及其呼叫的其他方法只能存取本機電腦的事件記錄檔,而無法刪除事件記錄檔。
SecurityAction.RequestMinimum:當Web系統的記錄檔位於程式集時,限制無法載入程式集。

補充資料:System.Security 命名空間


2.System.Security.Cryptography(Web加密與解密)

補充資料:System.Security.Cryptography 命名空間


3.System.Security.Principal(使用者安全控制):

(1)自訂驗證:透過使用GenericPrincipal和GenericIdentity自訂專門的角色和使用者身份資訊。

(2)Windows驗證:透過WindowsPrincipa和WindowsIdentity建立符合Windows安全認證標準的帳戶資訊,資訊的審核標準必須依據Windows使用者群組來確定。

補充資料:System.Security.Principal 命名空間


4.System.Security.Policy(程式安全控制):

(1)證據類別:

<1>發佈者簽名:指出程式集的作者及其可用性。
<2>強命名:為一套憑證,包括名稱、版本號、雜湊及公開金ㄧ
<3>雜湊:程式集的唯一識別碼。

(2)策略等級:

<1>Enterprise:表示Intranet中安裝主動目錄(AD)的機器。
<2>Machine:針對一個特定機器的所有使用者。
<3>User:只應用於一台特定機器上的一個特定使用者
<4>AppDomain:作用於整個執行緒域的使用者。

補充資料:System.Security.Policy 命名空間


5.System.Security.Permissions(程式存取控制):

補充資料:System.Security.Permissions 命名空間


6.System.Web.Security(驗證URL和檔案):

補充資料:System.Web.Security 命名空間




二、ASP.NET 4.0的安全性元件

1.登入控制項:使用者點擊登入按鈕後,控制項會呼叫membership驗證使用者的憑證。如果使用者的身份憑證有效,則利用表單驗證方法SetAuthCookie儲存使用的登入資料。


2.登入狀態控制項:

(1)LoginName(使用者名稱顯示控制項)

補充資料:LoginName 類別

(2)LoginStatus(登入狀態顯示控制項)

補充資料:LoginStatus 類別


3.密碼維護控制項:

(1)PasswordRecovery(密碼修復控制項)

補充資料:HOW TO:使用 ASP.NET PasswordRecovery 控制項啟用使用者密碼復原

(2)ChangePassword(密碼修改控制項)

補充資料:ChangePassword 類別


4.建立使用者精靈控制項:針對輸入文字方塊須採用Server.HtmlEncode(textbox.Text),將HTML字元轉化。

補充資料:HOW TO:自訂 ASP.NET CreateUserWizard 控制項




三、儲存的安全

1.保護設定檔的類別函數:

(1)DpapiProtectedConfigurationProvider Class:使用Windows內建的密碼學技術來加解密。

補充資料:DpapiProtectedConfigurationProvider 類別

(2)RsaProtectedConfigurationProvider Class:使用RSA公鑰加解密。

補充資料:RsaProtectedConfigurationProvider 類別


2.保護檢視狀態的五種方式:

(1)確保檢視狀態雜湊值
(2)使用MAC金鑰計算檢視狀態雜湊值(在Machine.config指定金鑰,而非讓ASP.NET自動產生)
(3)檢視狀態加密(ViewStateEncryptionMode應設為true)
(4)控制項狀態加密(呼叫RegisterRequiresViewStateEncryption)
(5)基於每個使用者的檢視狀態編碼(將ViewStateUserKey與每個使用者的一個唯一值相關聯)


3.開啟檢視保護開關:

  • 伺服器:在machine.config檔案中,設定<pages enableViewState="true"/>
  • 應用程式:在web.config檔案中,設定<pages enableViewState="true"/>
  • 頁面:在頁面原始程式碼中,使用<% @pages enableViewState="true"%>;或者在程式中設定Page.EnableViewState="true"
  • 控制項:在頁面原始程式碼中,設定控制項屬性EnableViewState="true"


4.加密演算法類別:

(1)對稱加密演算法SymmetricAlgorithm:

補充資料:SymmetricAlgorithm 類別

(2)非對稱加密演算法AsymmetricAlgorithm:

補充資料:AsymmetricAlgorithm 類別

(3)雜湊式加密演算法HashAlgorithm:

補充資料:HashAlgorithm 類別




四、讓ASP.NET/JSP與資料庫安全通訊

1.SQL植入攻擊的防範方法:

(1)過濾或轉換危險字元
(2)使用SqlParameter類別
(3)用正規表示式限制輸入(System.Text.RegularExpressions
(4)使用最小許可權
(5)拒絕已知的攻擊簽名,如drop、delete、insert或update等
(6)加密處理(HashPasswordForStoringInConfigFile
(7)在伺服器上處理錯誤


2.盡可能使用預存程序,而且應透過Parameters集合呼叫它們。


3.如果Web應用程式使用Windows身份驗證,應使用服務帳戶或執行序帳戶(如ASP.NET帳戶)來連接資料庫。


4.為使SQL Server能自動加密跨網路發送的憑據,通常會在資料庫伺服器上安裝伺服器憑證。此外,也可以使用Web伺服器和資料庫伺服器之間的IPSec加密通道,保護所有發送到資料庫伺服器和來自資料庫伺服器的流量。而要保護連接字串,則可使用DPAPI


5.進行資料庫連接時,應特別檢查資料存取碼是如何使用權限對呼叫方或程式進行授權的。要在資料庫中授權應用程式使用最低特權登入SQL伺服器,該登入帳戶只能經過選擇的預存程序。


6.程式應在使用者連接資料庫之前,根據角色或標識對其授權。角色檢查通常在應用程式的業務邏輯中進行,但若專案沒有明確區分業務和資料存取邏輯,則應在存取資料庫的方法中使用主體許可權要求。


7.若只希望公司或特定的開發單位撰寫的城市能夠使用資料存取元件,應使用一個強簽名屬性StrongNameIdentityPermissionAttribute,並要求呼叫方程式及擁有指定公開金鑰的強式名稱。


8.使用登錄檔根項HKEY_LOCAL_MACHINE,可提供受限的存取,此外,應將需要加密的字串儲存在Web.config檔案中,以利佈署。


9.Persist Security Info應設為false,參考資料:ADO数据库连接中的Integrated Security和Persist Security Info参数的作用


10.若應用程式利用ADO.NET的託管資料,提供程式的外部通用資料連結(UDL)檔案,則應使用NTFS的磁碟格式控制權限。

此外,UDL檔案並沒有加密,更安全的方法是使用DPAPI加密連接字串,並將其儲存在受限的登錄檔項。




五、把住使用者輸入關

1.輸入驗證控制項:

(1)RequiredFieldValidator:可強迫某個Web控制項輸入資料

(2)CompareValidator:可驗證使用者輸入的資料,並和某個值進行比較

(3)RangeValidator:限制使用者輸入的資料在指定的範圍內

(4)RegularExpressionValidator:可做更細微的限制

(5)CustomValidator:自訂資料的檢驗方式

(6)ValidationSummary:顯示尚未通過驗證的欄位

補充資料:[ASP.NET] 驗證控制項 / Validation Control


2.在ASP.NET中若不希望因validateRequest設為true,而導致使用者在輸入不安全資料或遭XSS時顯示的錯誤訊息,應改為如下作法:

在目前頁面增加Page_Error函數捕捉所有頁面處理過程中沒被處理的例外,並給使用者一個合法的顯示錯誤資訊。若目前頁面沒有Page_Error(),這個例外將會送到Global.asax的Application_Error()來處理,因此也可以在Application_Error()中寫通用的例外顯示錯誤處理函數。


3.頁面含有Rich Text Editor控制項,且又想避免遭XSS攻擊:

將輸入字串用HttpUtility.HtmlEncode()編碼,將其中的HTML標籤徹底禁止。然後再對安全標籤透過Replace()進行替換。例如希望有"<b>"標籤,則將"&lt;b&gt;"顯性的替換回"<b>"。




六、撰寫安全中介軟體

1.設計中介軟體的許可權:

(1)使用呼叫等級的身分驗證:

透過向服務元件程式集增加以下屬性:

[assembly:applicationAccessControl(Authentication = AuthenticationOption.Call)]

*該方式等同在元件服務中將應用程式的Properties交談視窗的Security標籤的Authentication level for calls設定為Call

(2)授權:

<1>啟用基於角色的安全性:

將以下屬性增加到服務元件程式集中:

[assembly:applicationAccessControl(true)]

*該方式等同在元件服務中選擇應用程式的Properties交談視窗的Security標籤的Enforce access checks for this application


<2>啟用元件級存取檢查:

將以下屬性增加到服務元件程式集中:

[assembly:applicationAccessControl(AccessChecksLevel=AccessChecksLevelOption.ApplicationComponent)]

*該方式等同在元件服務中選擇應用程式的Properties交談視窗的Security標籤的Perform access checks at the process and component level

<3>強制元件級存取檢查:

將以下屬性增加到服務元件類別:

[ComponentAccessControl(true)]
public class YourServicedComponent :ServicedComponent{}

*該方式等同在元件服務中選擇應用程式的Properties交談視窗的Security標籤的Enforce component level access checks

(3)設定管理:

<1>使用特權最少的帳戶:
<2>避免在物件建構函數字串中儲存機密資訊
<3>避免無約束的委派




七、建構可靠的Session

1.要避免重新產生過期的SessionID,可將sessionState設定元素的regenerateExpiredSessionId屬性設為true。




八、保護錯誤訊息

1.錯誤例外地引發準則:

(1)不要傳回錯誤程式,例外是報告框架中錯誤的主要方法。

(2)盡可能不對正常控制流使用異常。

(3)對於方法中傳入的參數,不要將錯誤報告作為參數加入。

(4)不要包含將例外作為傳回值或輸出參數傳回的公共成員。

(5)撰寫異常例外產生器。

(6)不要從例外篩選器中引發例外。

(7)避免從finally區塊中顯性引發例外。

(8)不要拋出new Exception()。

(9)不要把重要的例外資訊放在Message中。

(10)每個執行緒要有單獨的catch敘述。

(11)例外捕捉應被記錄。

(12)要記錄Exception的全部資訊,而不僅是Message。

(13)每個執行緒只能有一個catch。

(14)要把清理程式放在finally模組中。

(15)經常使用using。

(16)不要在錯誤條件下傳回特殊值。

(17)不要讓異常例外暗示資源的遺失。

(18)不要把例外處理方法作為從函數中傳回資訊的方法。

(19)為那些不該被忽略的錯誤撰寫異常。

(20)再次拋出例外時不要清空堆疊追蹤。

(21)避免在沒有增加語意值時就改變例外。

(22)例外應用serializable標識。

(23)有疑惑時不要斷言,拋出例外。

(24)不要重新建構自己的安全模組。

(25)不要使用無結構錯誤處理機制。


2.正確處理例外的準則:

(1)不要透過在框架程式中捕捉非特定例外的處理錯誤。

(2)避免在程式碼中捕捉非特定例外的處理錯誤。

(3)如果捕捉例外是為了傳輸例外,則不要排除任何特殊例外。

(4)如果了解特定例外在指定上下文中引發的條件,就捕捉例外。

(5)不要過多使用catch。

(6)避免將try-catch用於清理程式。

(7)捕捉並再次引發例外時,最好使用空參考。

(8)不要使用無參數的catch區塊處理不符合CLS的例外。


3.錯誤例外地捕捉:

(1)Exception和SystemException:

<1>不要引發System.Exception或System.SystemException

<2>不要在框架程式中捕捉System.Exception或System.SystemException,除非你打算再次引發

<3>避免捕捉System.Exception或System.SystemException,頂級例外值處理函式中除外

(2)ApplicationException:

一定要從T:System.Exception類別,而不是T:SystemException類別衍生自訂例外。

(3)InvalidOperationException:

<1>ArgumentException、ArgumentNullException和ArgumentOutOfRange Exception。

<2>不允許可公開呼叫的API顯性或隱性引發System.NullReferenceException、System.AccessViolationException、System.InvalidCastException或System.IndexOutOfRangeException,應進行參數化檢查以避免引發這些例外。

<3>使用StackOverflowException,不要顯性引發System.StackOverflowException。

<4>使用OutOfMemoryException,不要顯性引發System.OutOfMemoryException。

<5>使用ComException和SEHException,不要顯性引發System.Runtime.InteropServices.ComException或System.Runtime.Interop-Services.SEHException。

<6>使用ExecutionEngineException,不要顯性引發System.ExecutionEngineException。


4.在例外處理會嚴重影響性能時,應使用Tester-Doer模式。Tester對可能導致Doer引發例外的狀態執行測試,而測試剛好插入在引發例外的程式之前,進而防範了例外的發生。

*當在測試涉及可變物件的多執行緒應用程式中使用該模式時,可透過執行緒同步技術解決可能出現的狀態爭用問題。


5.對於可能在常見方案中引發例外的成員,可透過TryParse模式避免與例外相關的性能問題。

要實現TryParse模式,需要為常見方案中引發例外的操作提供兩種不同的方法:第一種方法X,執行該操作並在適當時引發例外;第二種方法TryX不引發例外,而是傳回一個Boolean值以指示成功或失敗。對TryX的成功呼叫鎖傳回的任何資料都透過使用out參數傳回。


6.控制錯誤訊息的安全原則:

(1)將應用程式設定為不向遠端使用者顯示詳細挫愈訊息。

在web.config中,對customErrors元素進行以下修改:
  • 將mode屬性設定為RemoteOnly,將應用程式設定為僅向本機使用者顯示詳細的錯誤。
  • 設定指向應用程式錯誤頁的defaultRedirect屬性。
  • 設定將錯誤重新導向到特定頁的<error>元素。

(2)在可能產生錯誤的任何敘述前後使用try-catch-finally。

(3)建立全域錯誤處理函式。

*若頁面中設定全域處理函式,則優先於在web.config檔案中的customErrors元素defaultRedirect屬性中指定的錯誤處理函式。

沒有留言:

張貼留言