安全性透明的程式碼,層級 1
透明度可協助開發人員撰寫更安全的 .NET Framework 程式庫,向部分信任的程式碼公開功能。 層級 1 透明度是 .NET Framework 2.0 版引入的,而且主要用於 Microsoft 中。 從 .NET Framework 4 版開始,您就可以使用層級 2 透明度。 不過,仍然保留層級 1 透明度,讓您可以識別必須使用先前安全性規則來執行的舊版程式碼。
重要事項 |
---|
您應該僅針對相容性指定層級 1 透明度。也就是說,您應該僅針對使用 .NET Framework 3.5 或舊版所開發而且使用 AllowPartiallyTrustedCallersAttribute 或沒有使用透明度模型的程式碼指定層級 1。例如,若為允許來自部分信任呼叫端 (APTCA) 之呼叫的 .NET Framework 2.0 組件,請使用層級 1 透明度。若為針對 .NET Framework 4 所開發的程式碼,請一律使用層級 2 透明度。 |
此主題包括下列章節:
層級 1 透明度模型
透明度屬性
安全性透明度範例
層級 1 透明度模型
當您使用層級 1 透明度時,就是使用將程式碼分為安全性透明、安全性安全關鍵和安全性關鍵方法的安全性模型。
您可以將整個組件、組件中的某些類別,或是類別中的某些方法,標示為安全性透明。 安全性透明程式碼無法評估權限。 這項限制有三個影響:
安全性透明的程式碼無法執行 Assert 動作。
符合安全性程式碼的任何連結需求,都會變成完整的要求。
必須在安全性透明程式碼中執行的任何不安全 (無法驗證) 的程式碼,都會導致 UnmanagedCode 安全性權限的完整需求。
這些規則是在執行時由 Common Language Runtime (CLR) 強制套用。 安全性透明程式碼會將它回呼的程式碼的所有安全性需求傳遞給呼叫者。 流經安全性透明程式碼的需求,不能評估權限。 如果低度信任的應用程式呼叫安全性透明程式碼並產生高權限的需求,則需求會流回低度信任程式碼且失敗。 安全性透明程式碼無法停止此需求,因為它不能執行判斷提示動作。 從完全信任程式碼呼叫的同一個安全性透明程式碼,會產生成功的需求。
安全性關鍵和安全性透明相反。 安全性關鍵程式碼是以完全信任方式執行,而且可以執行所有需要權限的作業。 安全性安全關鍵程式碼是通過廣泛安全性稽核的特權程式碼,可以確認該程式碼不會允許部分信任的呼叫端使用沒有存取權限的資源。
您必須明確套用透明度。 負責資料操作與邏輯的大部分程式碼通常可以標示為安全性透明,而負責執行權限升級的小部分程式碼則標示為安全性關鍵或安全性安全關鍵。
重要事項 |
---|
層級 1 透明度限制於組件範圍,這在組件之間沒有強制性。層級 1 透明度主要用於 Microsoft 內部進行安全性稽核。層級 1 組件內的安全性關鍵型別和成員可以由其他組件中的安全性透明程式碼存取。您應該在所有層級 1 安全性關鍵型別和成員執行完全信任的連結需求,這一點非常重要。安全性安全關鍵型別和成員還必須確認,呼叫端對於透過型別或成員存取的受保護資源必須擁有權限。 |
為了與舊版 .NET Framework 回溯相容,所有未加註透明度屬性的成員會被視為安全性安全關鍵。 所有未加註的型別會被視為透明。 沒有任何靜態分析規則可以用來驗證透明度。 因此,您可能需要在執行階段偵錯透明度錯誤。
透明度屬性
下表說明您可以用來加註程式碼透明度的三個屬性。
屬性 |
說明 |
---|---|
僅組件層級允許。 將組件中的所有型別和成員識別為安全性透明。 組件不能包含任何安全性關鍵程式碼。 |
|
在無 Scope 屬性的組件層級使用時,預設會將組件中的所有程式碼識別為安全性透明,但會指示組件可能包含安全性關鍵程式碼。 在類別層級使用時,將類別或方法識別為安全性關鍵,而不是類別的成員。 若要將所有成員設成安全性關鍵,請將 Scope 屬性設為 Everything。 在成員層級使用時,屬性只適用於該成員。 識別為安全性關鍵的類別或成員,可以執行權限升級。
重要事項
在層級 1 透明度,當安全性關鍵型別和成員被從組件外部呼叫時,可以視為安全性安全關鍵。您應該使用完全信任的連結要求來保護安全性關鍵型別和成員,以避免未經授權的權限升級。
|
|
識別可以由組件中之安全性透明程式碼存取的安全性關鍵程式碼。 否則安全性透明程式碼無法存取相同組件中,私人或內部安全性關鍵成員。 這麼做會影響安全性關鍵程式碼,並造成非預期的權限提高。 安全性安全關鍵程式碼應該接受嚴格的安全性稽核。
注意事項
安全性安全關鍵型別和成員必須驗證呼叫端的權限,以判斷呼叫端是否具有存取受保護資源的授權。
|
SecuritySafeCriticalAttribute 屬性可以讓安全性透明的程式碼存取相同組件中,安全性關鍵的成員。 將組件中的安全性透明及安全性關鍵程式碼,區分成兩個組件。 安全性透明程式碼無法查看安全性關鍵程式碼的私用或內部成員。 此外,安全性關鍵程式碼一般是為了存取公用介面而稽核。 您不希望私用或內部狀態在組件外還能存取,而要維持狀態隔離。 SecuritySafeCriticalAttribute 屬性會維持安全性透明與安全性關鍵程式碼之間的狀態隔離,並可在必要時覆寫隔離。 安全性透明程式碼無法存取私用或內部安全性關鍵程式碼,除非那些成員已經標示為 SecuritySafeCriticalAttribute。 套用 SecuritySafeCriticalAttribute 前,請將成員視為公開成員並加以稽核。
組件範圍的附註
下表說明在組件層級中使用安全性屬性的作用。
組件屬性 |
組件狀態 |
---|---|
部分信任組件無屬性 |
所有型別和成員為透明。 |
完全信任組件無屬性 (在全域組件快取或在 AppDomain 中識別為完全信任) |
所有型別為透明且所有成員為安全性安全關鍵。 |
SecurityTransparent |
所有型別和成員為透明。 |
SecurityCritical(SecurityCriticalScope.Everything) |
所有型別和成員為安全性關鍵。 |
SecurityCritical |
所有程式碼都預設為透明的。 不過,個別的型別和成員可以有其他屬性。 |
安全性透明度範例
若要使用 .NET Framework 2.0 透明度規則 (層級 1 透明度),請使用下列組件附註:
[assembly: SecurityRules(SecurityRuleSet.Level1)]
如果您要使整個組件透明以指示組件內不含任何關鍵程式碼,而且在任何情況下都不提高權限,可以使用下列屬性將透明度明確地新增至組件:
[assembly: SecurityTransparent]
如果您要混合相同組件中的關鍵及透明程式碼,可以使用 SecurityCriticalAttribute 屬性標示組件,以指示組件可以包含關鍵程式碼,如下所示:
[assembly: SecurityCritical]
如果您要執行安全性關鍵動作,必須以 SecurityCriticalAttribute 屬性明確的標示將執行關鍵動作的程式碼,如下列程式碼範例所示:
[assembly: SecurityCritical]
Public class A
{
[SecurityCritical]
private void Critical()
{
// critical
}
public int SomeProperty
{
get {/* transparent */ }
set {/* transparent */ }
}
}
public class B
{
internal string SomeOtherProperty
{
get { /* transparent */ }
set { /* transparent */ }
}
}
除了 Critical 方法 (明確標示為安全性關鍵) 外,前述程式碼是透明程式碼。 即使有組件層級 SecurityCriticalAttribute 屬性,透明度仍是預設的設定。