CA2102:在一般處理常式中攔截非 CLSCompliant 的例外狀況
型別名稱 |
CatchNonClsCompliantExceptionsInGeneralHandlers |
CheckId |
CA2102 |
分類 |
Microsoft.Security |
中斷變更 |
中斷 |
原因
組件 (Assembly) 中未標記 RuntimeCompatibilityAttribute 或已標記 RuntimeCompatibility(WrapNonExceptionThrows = false) 的成員包含可處理 Exception 的 catch 區塊,而且未包含緊接在後面的一般 catch 區塊。此規則會忽略 Visual Basic 組件。
規則描述
處理 Exception 的 catch 區塊會攔截符合 Common Language Specification (CLS) 標準的所有例外狀況。但是,它不會攔截不符合 CLS 標準的例外狀況。不符合 CLS 標準的例外狀況可能從機器碼,或是從 Microsoft Intermediate Language (MSIL) 組譯工具產生的 Managed 程式碼擲回。請注意,C# 和 Visual Basic 編譯器不允許擲回不符合 CLS 標準的例外狀況,而 Visual Basic 則不會攔截不符合 CLS 標準的例外狀況。如果 catch 區塊的目的是要處理所有的例外狀況,請使用下列一般 catch 區塊語法。
C#: catch {}
C++: catch(...) {} 或 catch(Object^) {}
當 catch 區塊移除了先前允許的使用權限時,未處理之不符合 CLS 標準的例外狀況將會變成安全性問題。由於系統不會攔截不符合 CLS 標準的例外狀況,因此擲回不符合 CLS 標準之例外狀況的惡意方法可能使用提高的權限來執行。
如何修正違規
若要在目的是攔截所有例外狀況時修正此規則的違規情形,請替換或加入一般 catch 區塊,或將組件標記為 RuntimeCompatibility(WrapNonExceptionThrows = true)。如果 catch 區塊中移除了使用權限,請在一般 catch 區塊中複製功能。如果您的目的不是要處理所有的例外狀況,請將處理 Exception 的 catch 區塊取代成處理特定例外狀況類型的 catch 區塊。
隱藏警告的時機
如果 try 區塊不包含任何可能產生不符合 CLS 標準之例外狀況的陳述式,則可以放心地隱藏這項規則的警告。由於任何機器碼或 Managed 程式碼都有可能擲回不符合 CLS 標準的例外狀況,因此必須具備可在 try 區塊內所有程式碼路徑中執行之所有程式碼的知識。請注意,Common Language Runtime 不會擲回不符合 CLS 標準的例外狀況。
範例
下列範例顯示擲回不符合 CLS 標準之例外狀況的 MSIL 類別 (Class)。
.assembly ThrowNonClsCompliantException {}
.class public auto ansi beforefieldinit ThrowsExceptions
{
.method public hidebysig static void
ThrowNonClsException() cil managed
{
.maxstack 1
IL_0000: newobj instance void [mscorlib]System.Object::.ctor()
IL_0005: throw
}
}
下列範例顯示包含符合此規則之一般 catch 區塊的方法。
// CatchNonClsCompliantException.cs
using System;
namespace SecurityLibrary
{
class HandlesExceptions
{
void CatchAllExceptions()
{
try
{
ThrowsExceptions.ThrowNonClsException();
}
catch(Exception e)
{
// Remove some permission.
Console.WriteLine("CLS compliant exception caught");
}
catch
{
// Remove the same permission as above.
Console.WriteLine("Non-CLS compliant exception caught.");
}
}
static void Main()
{
HandlesExceptions handleExceptions = new HandlesExceptions();
handleExceptions.CatchAllExceptions();
}
}
}
將前述範例編譯如下:
ilasm /dll ThrowNonClsCompliantException.il
csc /r:ThrowNonClsCompliantException.dll CatchNonClsCompliantException.cs