Důležité informace o zabezpečení pro reflexi

Reflexe ion poskytuje možnost získat informace o typech a členech a přistupovat k členům (to znamená volání metod a konstruktorů, získání a nastavení hodnot vlastností, přidání a odebrání obslužných rutin událostí atd.). Použití reflexe k získání informací o typech a členech není omezeno. Všechny kódy můžou použít reflexi k provedení následujících úloh:

  • Umožňuje vytvořit výčet typů a členů a prozkoumat jejich metadata.
  • Zobrazení výčtu a zkoumání sestavení a modulů

Použití reflexe pro přístup k členům naproti tomu podléhá omezením. Počínaje rozhraním .NET Framework 4 může reflexe přistupovat k důležitým členům zabezpečení pouze důvěryhodný kód. Kromě toho může reflexe použít pouze důvěryhodný kód pro přístup k nepublikovaným členům, kteří by nebyli přímo přístupní ke zkompilovanému kódu. Nakonec kód, který používá reflexi pro přístup k bezpečnému kritickému členu, musí mít libovolná oprávnění, která vyžadují bezpečné členy stejně jako u zkompilovaného kódu.

V souladu s nezbytnými oprávněními může kód použít reflexi k provedení následujících typů přístupu:

  • Přístup k veřejným členům, které nejsou kritické pro zabezpečení

  • Přístup k nepublikovaným členům, které by byly přístupné pro zkompilovaný kód, pokud tyto členy nejsou kritické pro zabezpečení. Mezi příklady takových neveřejných členů patří:

    • Chráněni členy základních tříd volajícího kódu. (V reflexi se to označuje jako přístup na úrovni rodiny.)

    • internal členy (Friend členy v jazyce Visual Basic) v sestavení volajícího kódu. (V reflexi se to označuje jako přístup na úrovni sestavení.)

    • Soukromé členy jiných instancí třídy, které obsahují volající kód.

Například kód spuštěný v doméně aplikace v izolovaném prostoru (sandbox) je omezený na přístup popsaný v tomto seznamu, pokud doména aplikace nepodělí další oprávnění.

Počínaje aktualizací Service Pack 1 rozhraní .NET Framework 2.0 se pokus o přístup k členům, které jsou normálně nepřístupné, generuje požadavek na sadu udělení cílového objektu a navíc ReflectionPermission s příznakem ReflectionPermissionFlag.MemberAccess . Kód, který běží s úplným vztahem důvěryhodnosti (například kód v aplikaci spuštěné z příkazového řádku), může vždy splňovat tato oprávnění. (To podléhá omezením přístupu ke členům kritickým pro zabezpečení, jak je popsáno dále v tomto článku.)

Volitelně může doména aplikace v izolovaném prostoru (sandbox) udělit ReflectionPermissionReflectionPermissionFlag.MemberAccess příznak, jak je popsáno v části Přístup k členům, kteří jsou normálně nepřístupní, dále v tomto článku.

Přístup k důležitým členům zabezpečení

Člen je kritický pro zabezpečení, pokud má SecurityCriticalAttribute, pokud patří k typu, který SecurityCriticalAttributemá , nebo pokud je v sestavení kritické pro zabezpečení. Počínaje rozhraním .NET Framework 4 jsou pravidla pro přístup ke členům kritickým pro zabezpečení následující:

  • Transparentní kód nemůže použít reflexi pro přístup k důležitým členům zabezpečení, i když je kód plně důvěryhodný. A MethodAccessException, FieldAccessExceptionnebo TypeAccessException je vyvolán.

  • Kód, který běží s částečným vztahem důvěryhodnosti, se považuje za transparentní.

Tato pravidla jsou stejná, jestli je člen kritický pro zabezpečení přístupný přímo zkompilovaným kódem nebo přístupný pomocí reflexe.

Kód aplikace, který se spouští z příkazového řádku, běží s úplným vztahem důvěryhodnosti. Pokud není označený jako transparentní, může použít reflexi pro přístup ke členům kritickým pro zabezpečení. Pokud je stejný kód spuštěn s částečným vztahem důvěryhodnosti (například v doméně aplikace v izolovaném prostoru (sandbox) úroveň důvěryhodnosti sestavení určuje, jestli má přístup k kódu kritickému pro zabezpečení: Pokud má sestavení silný název a je nainstalován v globální mezipaměti sestavení, jedná se o důvěryhodné sestavení a může volat členy kritické pro zabezpečení. Pokud není důvěryhodná, stane se transparentní, i když nebyla označena jako transparentní a nemůže přistupovat k důležitým členům zabezpečení.

Reflexe a transparentnost

Počínaje rozhraním .NET Framework 4 určuje modul CLR úroveň transparentnosti typu nebo člena z několika faktorů, včetně úrovně důvěryhodnosti sestavení a úrovně důvěryhodnosti domény aplikace. Reflexe ion poskytuje IsSecurityCritical, IsSecuritySafeCriticala IsSecurityTransparent vlastnosti, které umožňují zjistit úroveň průhlednosti typu. V následující tabulce jsou uvedeny platné kombinace těchto vlastností.

Úroveň zabezpečení IsSecurityCritical IsSecuritySafeCritical IsSecurityTransparent
Kritické true false false
Sejf kritické true true false
Průhledné false false true

Použití těchto vlastností je mnohem jednodušší než zkoumání poznámek zabezpečení sestavení a jeho typů, kontrole aktuální úrovně důvěryhodnosti a pokusu o duplikování pravidel modulu runtime. Například stejný typ může být kritický pro zabezpečení při spuštění z příkazového řádku nebo transparentní zabezpečení při spuštění v doméně aplikace v izolovaném prostoru (sandbox).

Existují podobné vlastnosti na MethodBase, FieldInfo, TypeBuilderMethodBuilder, a DynamicMethod třídy. (Pro jiné reflexe a reflexe generují abstrakce, atributy zabezpečení se použijí u přidružených metod, například v případě vlastností, které se použijí na přístupové objekty vlastností.)

Přístup k členům, které jsou obvykle nepřístupné

Pokud chcete použít reflexi k vyvolání členů, které jsou nepřístupné podle pravidel přístupnosti modulu CLR (Common Language Runtime), musí mít váš kód udělená jedno ze dvou oprávnění:

  • Chcete-li povolit vyvolání jakéhokoli nepublikovaného člena: Kód musí být udělen ReflectionPermission příznakem ReflectionPermissionFlag.MemberAccess .

    Poznámka:

    Ve výchozím nastavení zásady zabezpečení toto oprávnění odepře kódu, který pochází z internetu. Toto oprávnění by nikdy nemělo být uděleno kódu, který pochází z internetu.

  • Pokud chcete kódu povolit vyvolání libovolného nepublikovaného členu, pokud je sada udělení sestavení, která obsahuje vyvolaný člen, je stejná jako nebo podmnožina sestavení, která obsahuje vyvolání kódu: Kód musí být udělen ReflectionPermission příznakem ReflectionPermissionFlag.RestrictedMemberAccess .

Předpokládejme například, že udělíte oprávnění k internetu domény aplikace plus ReflectionPermission s příznakem ReflectionPermissionFlag.RestrictedMemberAccess a pak spustíte internetovou aplikaci se dvěma sestaveními, A a B.

  • Sestavení A může použít reflexi pro přístup k soukromým členům sestavení B, protože sada grantů sestavení B neobsahuje žádná oprávnění, která nebyla udělena.

  • Sestavení A nemůže použít reflexi pro přístup k soukromým členům sestavení rozhraní .NET Framework, jako je například mscorlib.dll, protože mscorlib.dll je plně důvěryhodný a proto má oprávnění, která nebyla udělena sestavení A. Vyvolá MemberAccessException se, když zabezpečení přístupu kódu provede zásobník za běhu.

Serializace

Pro serializaci SecurityPermissionSecurityPermissionAttribute.SerializationFormatter poskytuje příznak možnost získat a nastavit členy serializovatelných typů bez ohledu na přístupnost. Toto oprávnění umožňuje kódu zjišťovat a měnit privátní stav instance. (Kromě udělení příslušných oprávnění musí být typ označen jako serializovatelný v metadatech.)

Parametry Type MethodInfo

Vyhněte se psaní veřejných členů, kteří přebírají MethodInfo parametry, zejména pro důvěryhodný kód. Tito členové můžou být zranitelnější vůči škodlivému kódu. Představte si například veřejného člena ve vysoce důvěryhodném MethodInfo kódu, který přebírá parametr. Předpokládejme, že veřejný člen nepřímo volá metodu Invoke zadaného parametru. Pokud veřejný člen neprovede potřebné kontroly oprávnění, volání Invoke metody bude vždy úspěšné, protože systém zabezpečení určuje, že volající je vysoce důvěryhodný. I když škodlivý kód nemá oprávnění přímo vyvolat metodu, může to přesto provést nepřímo voláním veřejného člena.

Informace o verzi

  • Počínaje rozhraním .NET Framework 4 nemůže transparentní kód používat reflexi pro přístup ke členům kritickým pro zabezpečení.

  • Příznak ReflectionPermissionFlag.RestrictedMemberAccess je zaveden v rozhraní .NET Framework 2.0 Service Pack 1. Starší verze rozhraní .NET Framework vyžadují ReflectionPermissionFlag.MemberAccess příznak pro kód, který používá reflexi pro přístup k neveřejných členů. Toto je oprávnění, které by nikdy nemělo být uděleno částečně důvěryhodnému kódu.

  • Počínaje rozhraním .NET Framework 2.0 nevyžaduje použití reflexe k získání informací o nepublikovaných typech a členech žádná oprávnění. V dřívějších verzích ReflectionPermissionReflectionPermissionFlag.TypeInformation se vyžaduje příznak.

Viz také