Microsoft 最小建議規則:程式碼分析規則集
您可以使用「Microsoft 最小建議規則」規則集,將焦點放在程式碼中最重要的問題,包括潛在的安全性漏洞、應用程式損毀,以及其他重要的邏輯和設計錯誤。 您應在任何為專案建立的自訂規則集內包含此規則集。
規則 |
說明 |
---|---|
類別會宣告及實作型別為 System.IDisposable 的執行個體欄位,且該類別不會實作 IDisposable。 宣告 IDisposable 欄位的類別會間接擁有 Unmanaged 資源,且應實作 IDisposable 介面。 |
|
事件處理常式方法會採用兩個參數。 第一個的型別為 System.Object 且名稱為 "sender"。 這是引發事件的物件。 第二個參數的型別為 System.EventArgs 且名稱為 "e"。 這是與事件關聯的資料。 事件處理常式方法不應該傳回值;在 C# 程式設計語言中,這是由 void 傳回型別所表示。 |
|
.NET Framework 會使用版本號碼以便唯一識別組件,並繫結至強式名稱組件中的型別。 版本號碼會與版本和發行者 (Publisher) 原則一起使用。 應用程式預設只會與建置它們的組件版本一起執行。 |
|
非密封外部可見的型別會提供公用介面的明確方法實作,但未提供同名的替代外部可見方法。 |
|
配置 Unmanaged 資源的型別應實作 IDisposable,讓呼叫端視需要釋放這些資源,並且縮短持有資源之物件的存留期。 |
|
平台引動方法,例如以 System.Runtime.InteropServices.DllImportAttribute 屬性標記的方法,或在 Visual Basic 中使用 Declare 關鍵字定義的方法,都會存取 Unmanaged 程式碼。 這些方法應該是 NativeMethods、SafeNativeMethods 或 UnsafeNativeMethods 類別。 |
|
只有在衍生方法的參數簽章因型別衍生時比基底方法參數簽章中的型別還要弱時,基底型別中的方法才會被衍生型別中的相同具名方法所隱藏。 |
|
所有的 IDisposable 型別都需正確地實作 Dispose 模式。 |
|
不可擲回例外狀況 (Exception) 的方法卻擲回例外狀況。 |
|
便捷鍵也稱為快速鍵,可讓鍵盤使用 ALT 鍵存取控制項。 當多個控制項具有重複的便捷鍵時,就無法妥善定義便捷鍵的行為。 |
|
公用或受保護的方法會以 System.Runtime.InteropServices.DllImportAttribute 屬性標記。 有可能是找不到 Unmanaged 程式庫,或是方法不符合程式庫中的函式。 |
|
公用型別中公用或保護的方法具有 System.Runtime.InteropServices.DllImportAttribute 屬性 (也會由 Visual Basic 中的 Declare 關鍵字實作)。 但不得公開 (Expose) 此類方法。 |
|
COM 可見值型別以設為 LayoutKind.Auto 的 System.Runtime.InteropServices.StructLayoutAttribute 屬性標記。 可以在 .NET Framework 的版本間變更這些型別的配置,這將會中斷必須有特定配置的 COM 用戶端。 |
|
會對 Marshal.GetLastWin32Error 方法或對等 Win32 GetLastError 函式進行呼叫,而且緊接在前的呼叫並不是平台叫用方法。 |
|
COM 可見型別會衍生自不是 COM 可見的型別。 |
|
型別會宣告以 System.Runtime.InteropServices.ComRegisterFunctionAttribute 屬性標記的方法,但是不並宣告以 System.Runtime.InteropServices.ComUnregisterFunctionAttribute 屬性標記的方法,反之亦然。 |
|
此規則會尋找以 Win32 函式為目標 (具有指向 OVERLAPPED 結構參數的指標) 的平台叫用方法宣告,且相對應的 Managed 參數不是指向 System.Threading.NativeOverlapped 結構的指標。 |
|
這個規則會檢查在 64 位元作業系統上封送處理 Unmanaged 程式碼時,宣告為明確配置的結構是否會正確地配置。 |
|
這項規則會評估每個參數的大小和 P/Invoke 的傳回值,並且在 32 位元和 64 位元作業系統上封送處理至 Unmanaged 程式碼時驗證其大小是否正確。 |
|
因為可能會發生例外事件以防止執行物件的完成項,所以應在物件的所有參考都超出範圍之前,明確處置物件。 |
|
可以跨應用程式定義域範圍直接存取的物件,即所謂具有弱式識別的物件。 嘗試取得具有弱式識別之物件鎖定的執行緒,可以被不同應用程式定義域中具有相同物件鎖定的第二個執行緒所封鎖。 |
|
方法會使用透過字串引數所建置的字串,將 System.Data.IDbCommand.CommandText 屬性設定為方法。 這項規則假設字串引數包含使用者輸入。 從使用者輸入所建置的 SQL 命令字串很容易遭到 SQL 插入 (SQL Injection) 攻擊。 |
|
平台叫用成員允許部分信任的呼叫端、具有字串參數,並且未明確封送處理字串。 這樣會造成安全性弱點。 |
|
公用或受保護的實值型別受到資料存取或連結要求保護。 |
|
指標不為私用、內部或唯讀。 惡意的程式碼可變更指標值,進而可能會允許存取記憶體中的任意位置,或是造成應用程式或系統失敗。 |
|
公用或受保護的型別包含公用欄位,而且受到連結要求保護。 如果程式碼可存取受連結要求保護的型別執行個體,則程式碼不必滿足連結要求即可存取型別的欄位。 |
|
方法不應該同時具有相同動作的方法層級和型別層級宣告式安全性。 |
|
當完全信任的組件中出現 APTCA (AllowPartiallyTrustedCallers) 屬性,並且組件在不允許部分信任呼叫端的另一個組件中執行程式碼時,可能會發生安全性弱點攻擊。 |
|
當完全信任的組件中出現 APTCA (AllowPartiallyTrustedCallers) 屬性,並且組件中的型別會繼承自不允許部分信任之呼叫端的型別時,就可能會發生安全性弱點攻擊。 |
|
公用或受保護的成員具有連結要求,而且是由未執行任何安全性檢查的成員所呼叫。 連結要求只會檢查立即呼叫端的使用權限。 |
|
這項規則會使方法符合它的基底方法,即另一個型別中的介面或虛擬方法,然後比較每個方法上的連結要求。 如果違反這項規則,則惡意呼叫端只需呼叫不安全的方法,就可以略過連結要求。 |
|
公用或受保護的方法包含 try/finally 區塊。 finally 區塊似乎會重設安全性狀態,而且不會封入 finally 區塊中。 |
|
公用 unsealed 型別受到連結要求保護,並且具有可以覆寫的方法。 此型別或方法都不是以繼承要求保護的。 |
|
型別會參與使用 SecurityCriticalAttribute 屬性標記的型別等價或型別本身,或是型別的成員或欄位。 當任何關鍵型別包含的關鍵方法或欄位有參與型別等價時,就會針對此型別引發此規則。 當 CLR 偵測到這種型別時,它不會在執行階段使用 TypeLoadException 載入此型別。 一般而言,當使用者手動實作型別等價 (而非依賴 tlbimp 而由編譯器執行型別等價) 時,會引發此規則。 |
|
Silverlight 應用程式的程式碼不能使用內含 SecurityCriticalAttribute 的型別和成員。 安全性關鍵型別和成員只能由信任的程式碼在 .NET Framework for Silverlight 類別庫中使用。 由於衍生類別中的公用或受保護建構所具有的透明度必須大於或等於其基底類別,因此應用程式中的類別不可衍生自標記為 SecurityCritical 的類別。 |
|
當方法會將使用 SecurityCriticalAttribute 標記的委派繫結到透明方法,或繫結到使用 SecuritySafeCriticalAttribute 標記的方法時,就會針對此方法發出警告。 此警告也會針對將透明或安全關鍵性的委派繫結至關鍵方法的方法引發。 |
|
當使用 SecurityCriticalAttribute 標記的方法覆寫透明方法,或覆寫使用 SecuritySafeCriticalAttribute 標記的方法時,就會引發此規則。 當透明或使用 SecuritySafeCriticalAttribute 來標記的方法覆寫使用 SecurityCriticalAttribute 來標記的方法時,也會引發此規則。 覆寫虛擬方法或實作介面時會套用此規則。 |
|
方法包含無法驗證的程式碼,或以傳址方式傳回型別。 當安全性透明程式碼嘗試執行無法驗證的 Microsoft Intermediate Language (MISL) 時,就會引發此規則。 不過,此規則不包含完整的 IL 驗證器,而是使用啟發方式來擷取多數的 MSIL 驗證違規情形。 |
|
安全性透明方法會呼叫使用 SuppressUnmanagedCodeSecurityAttribute 屬性標記的方法。 |
|
安全性透明方法會呼叫未使用 APTCA 標記之組件中的方法,或是安全性透明方法會滿足型別或方法的 LinkDemand。 |
|
安全性透明方法會呼叫未使用 APTCA 標記之組件中的方法,或是安全性透明方法會滿足型別或方法的 LinkDemand。 |
|
標記為 SecurityTransparentAttribute 的程式碼並未具備足夠的使用權限可以進行判斷提示 (Assert)。 |
|
在任何直接呼叫進入機器碼的透明方法上 (例如,透過 P/Invoke),都會引發此規則。 違反此規則會導致層級 2 透明度模型出現 MethodAccessException,而在層級 1 透明度模型會出現對 UnmanagedCode 的完整要求。 |
|
例外狀況遭到重新擲回,而且已在 throw 陳述式中明確指定此例外狀況。 如果例外狀況是透過在陳述式中指定例外狀況而重新擲回,則會遺失在擲回例外狀況之原始方法和目前方法之間呼叫的方法清單。 |
|
方法實作包含程式碼路徑,可在相同物件上造成多個 System.IDisposable.Dispose 呼叫或 Dispose 對等用法 (例如,部分型別上的 Close() 方法)。 |
|
實值型別會宣告明確的靜態建構函式。 若要修正此規則的違規情形,請在宣告所有靜態資料時將靜態資料初始化,並移除靜態建構函式。 |
|
型別中繼承自 System.EnterpriseServices.ServicedComponent 的方法是以 System.Web.Services.WebMethodAttribute 標示。 因為 WebMethodAttribute 和 ServicedComponent 方法具有衝突的內容和交易流程的行為及需求,所以方法的行為在某些情節中會是不正確的。 |
|
實作 System.IDisposable 的型別宣告了也實作 IDisposable 之型別的欄位。 宣告型別的 Dispose 方法不會呼叫欄位的 Dispose 方法。 |
|
當建構函式呼叫虛擬方法時,有可能尚未執行叫用此方法之執行個體的建構函式。 |
|
實作 System.IDisposable 且具有建議 Unmanaged 資源用法之欄位的型別,未實作如 Object.Finalize 所述的完成項。 |
|
最終化必須透過繼承階層架構 (Inheritance Hierarchy) 進行傳播。 若要確保這一點,則型別必須在它們自己的 Finalize 方法中呼叫基底類別 Finalize 方法。 |
|
若要修正此規則的違規情形,請實作序列化建構函式。 針對密封類別,讓建構函式成為 private,否則為 protected。 |
|
STAThreadAttribute 表示應用程式的 COM 執行緒模型為單一執行緒 Apartment。 在使用 Windows Form 的任何應用程式之進入點上必須有此屬性。如果省略的話,Windows 元件就無法正常運作。 |
|
可序列化之型別中所宣告之型別的執行個體 (Instance) 欄位是不可序列化的。 |
|
若要修正此規則的違規情形,請從對應的衍生型別方法或建構函式,呼叫基底型別 GetObjectData 方法或序列化建構函式。 |
|
若要讓 Common Language Runtime 辨認為可序列化,即使型別透過 ISerializable 介面的實作使用自訂序列化常式,型別仍必須以 SerializableAttribute 屬性標記。 |
|
處理序列化事件的方法沒有正確的簽章、傳回型別或可視性。 |
|
若要修正此規則的違規情形,請將 GetObjectData 方法設為可見和可覆寫的,並確定所有執行個體欄位都加入序列化處理序中,或已明確標記 NonSerializedAttribute 屬性。 |
|
傳遞至 System.String.Format 的格式引數不包含對應至每個物件引數的格式項目,反之亦然。 |
|
此運算式針對 Single.Nan 或 Double.Nan 測試值。 使用 Single.IsNan(Single) 或 Double.IsNan(Double) 即可測試值。 |