CA2102:在一般處理常式中攔截非 CLSCompliant 的例外狀況
型別名稱 |
CatchNonClsCompliantExceptionsInGeneralHandlers |
CheckId |
CA2102 |
分類 |
Microsoft.Security |
中斷變更 |
中斷 |
原因
組件 (Assembly) 中未標記 RuntimeCompatibilityAttribute 或已標記 RuntimeCompatibility(WrapNonExceptionThrows = false) 的成員包含可處理 System.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