Sdílet prostřednictvím


Bezpečnostní úvahy pro reflexi

Reflexe 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.
  • Vyjmenovat a prozkoumat sestavení a moduly.

Použití reflexe pro přístup k členům naproti tomu podléhá omezením. Počínaje rozhraním .NET Framework 4 může pouze důvěryhodný kód pomocí reflexe přistupovat k členům kritickým pro zabezpečení. Kromě toho může pouze důvěryhodný kód použít reflexi k přístupu k neveřejným členům, které by nebyly přímo přístupné skompilovanému kódu. Nakonec kód, který používá reflexi pro přístup k bezpečně kritickému členu, musí mít taková oprávnění, jaká vyžaduje bezpečně kritický člen, stejně jako je tomu 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řistupujte k veřejným členům, kteří nejsou kritičtí 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ěné č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á obsahuje 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 verzí Service Pack 1 pro rozhraní .NET Framework 2.0 pokus o přístup k členům, které jsou obvykle nepřístupné, generuje požadavek na sadu udělení cílového objektu plus 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 sandboxová doména aplikace udělit ReflectionPermission s příznakem ReflectionPermissionFlag.MemberAccess, 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 ke členům Security-Critical

Člen je kritický pro zabezpečení, pokud má SecurityCriticalAttribute, pokud patří k typu, který má SecurityCriticalAttribute, nebo pokud je v sestavení, které je 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, FieldAccessException nebo TypeAccessException je vyhozena.

  • 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 plnou důvěrou. 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čnou důvěrou (například v sandboxové aplikační doméně), úroveň důvěryhodnosti sestavení určuje, jestli může přistupovat ke kódu kritickému pro zabezpečení: Pokud má sestavení silný název a je nainstalováno v globální mezipaměti sestavení, je to 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 poskytuje IsSecurityCritical, IsSecuritySafeCriticala IsSecurityTransparent vlastnosti, které vám umožní zjistit úroveň průhlednosti typu. V následující tabulce jsou uvedeny platné kombinace těchto vlastností.

Úroveň zabezpečení Je kritické pro bezpečnost IsSecuritySafeCritical IsSecurityTransparent
Kritický true false false
Bezpečnostně kritické true true false
Transparentní 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ý z hlediska zabezpečení při spuštění z příkazového řádku nebo transparentní z hlediska zabezpečení při spuštění v doméně aplikace v sandboxu.

Existují podobné vlastnosti na MethodBase, FieldInfo, TypeBuilderMethodBuilder, a DynamicMethod třídy. (Pro jiné odrazy a odrazy vytvářejí abstrakce, atributy zabezpečení se uplatňují na přidružené metody; například v případě vlastností se aplikují na přístupové metody 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 neveřejného člena, kódu musí být uděleno oprávnění s příznakem ReflectionPermissionReflectionPermissionFlag.MemberAccess.

    Poznámka:

    Zásady zabezpečení ve výchozím nastavení odepřou toto oprávnění 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 neveřejného člena, pokud je sada oprávnění sestavení, které obsahuje vyvolaný člen, stejná jako, nebo je podmnožinou sady oprávnění sestavení, které obsahuje vyvolávající kód, musí být vašemu kódu udělen ReflectionPermission s 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 techniku reflexe pro přístup k soukromým členům sestavení B, protože sada oprávnění sestavení B neobsahuje žádná oprávnění, která nebyla udělena sestavení A.

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

Serializace

Pro serializaci SecurityPermission s příznakem SecurityPermissionAttribute.SerializationFormatter poskytuje 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 typu MethodInfo

Vyhněte se psaní veřejných metod, které přijímají MethodInfo parametry, zejména pro důvěryhodnou část kódu. 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ý prostřednictvím reflexe přistupuje k neveřejným členům. 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 je vyžadován příznak ReflectionPermission s ReflectionPermissionFlag.TypeInformation.

Viz také