反映的安全性考量
更新:2007 年 11 月
反映 (Reflection) 提供取得與型別和成員相關資訊的能力,以及存取成員的能力。存取非公用成員可能會有安全性風險。因此,存取非公用成員的程式碼必須使用具有適當旗標的 ReflectionPermission。此外,某些工作也需要使用 SecurityPermission,例如提供辨識項、執行 Unmanaged 程式碼,以及序列化物件。
所有程式碼可以不需使用權限而使用反映來執行下列工作:
列舉型別和成員,並檢查它們的中繼資料 (Metadata)。
列舉及檢查組件和模組。
存取公用成員。
存取呼叫端程式碼之基底類別 (Base Class) 的 protected 成員 (在反映中,這稱為系列層級 (Family-level) 的存取)。
在呼叫端程式碼的組件中存取 internal 成員 (Visual Basic 中為 Friend 成員) (在反映中,這稱為組件層級 (Assembly-level) 的存取)。
存取非公用成員
若要使用反映來叫用無法根據 Common Language Runtime 之存取範圍規則對其存取的成員,您必須對程式碼授與兩種使用權限的其中一種:
若要允許程式碼叫用任何非公用成員:含 ReflectionPermissionFlag.MemberAccess 旗標的 ReflectionPermission。
注意事項: 根據預設,安全性原則會拒絕來自網際網路的程式碼使用此權限。這項使用權限永遠不應該授與來自網際網路的程式碼。
若要在包含叫用之成員的組件授權集與包含叫用程式碼之組件的授權集相同,或包含叫用程式碼之組件的子集時,允許程式碼叫用任何非公用程式:含 ReflectionPermissionFlag.RestrictedMemberAccess 旗標的 ReflectionPermission。
例如,假設您授與某個應用程式定義域網際網路使用權限,再加上含 ReflectionPermissionFlag.RestrictedMemberAccess 旗標的 ReflectionPermission,接著執行內含兩個組件 (A 和 B) 的網際網路應用程式。
組件 A 可以使用反映來存取組件 B 的私用成員,因為組件 B 不包含任何未授與 A 的使用權限。
組件 A 無法使用反映來存取 .NET Framework 組件的私用成員 (如 mscorlib.dll),因為 mscorlib.dll 是完全受信任的,因此不會授與給組件 A。當程式碼存取安全性在執行階段逐一查看堆疊時,會擲回 MemberAccessException。
如需授與含 ReflectionPermissionFlag.RestrictedMemberAccess 旗標之 ReflectionPermission 的沙箱化應用程式定義域範例,請參閱逐步解說:在部分信任案例中發出程式碼。
序列化
針對序列化 (Serialization) 的部分,含 SecurityPermissionAttribute.SerializationFormatter 旗標的 SecurityPermission 提供取得及設定可序列化型別之成員的能力,而不管其存取範圍為何。這個使用權限可讓程式碼探索 (Discovery) 並變更執行個體 (Instance) 的私用狀態 (除了被授予適當使用權限之外,型別還必須在中繼資料 (Metadata) 中被標記為可序列化)。
連結要求檢查
如果方法或委派具有使用權限 P 的 LinkDemand,執行階段將會針對方法或委派的呼叫端執行連結要求檢查,以確認呼叫端獲得授與使用權限 P。此連結要求檢查會在型別資訊的探索和引動過程時發生。
避免撰寫型別為 MethodInfo 的參數
請避免撰寫採用 MethodInfo 參數的公用 API,尤其是高度受信任的程式碼。此類 API 可能會更容易受到惡意程式碼的損害。例如,試想在高度受信任的程式碼中採用 MethodInfo 參數的公用 API。假設公用 API 以提供的參數間接呼叫 Invoke 方法。如果公用 API 不執行必要的使用權限檢查,由於安全性系統決定呼叫端受到高度信任,所以對於 Invoke 方法的呼叫一定都會成功。即使惡意程式碼沒有使用權限而直接叫用方法,它仍可以呼叫公用 API 間接做到這點。
版本資訊
ReflectionPermissionFlag.RestrictedMemberAccess 旗標是在 .NET Framework 2.0 版 Service Pack 1 加入的。對於使用反映存取非公用成員的程式碼,舊版 .NET Framework 需要 ReflectionPermissionFlag.MemberAccess 旗標。這個使用權限永遠都不應該授與部分信任的程式碼。
注意事項: |
---|
若要使用 ReflectionPermissionFlag.RestrictedMemberAccess 旗標,您的應用程式應將目標設定為 .NET Framework 3.5 版。如需詳細資訊,請參閱 .NET Framework 3.5 架構。 |
從 .NET Framework 2.0 開始,使用反映來取得非公用型別和成員的相關資訊時,並不需要任何使用權限。在舊版中,則需要含 ReflectionPermissionFlag.TypeInformation 旗標的 ReflectionPermission。