Condividi tramite


Problemi di sicurezza con la reflection emit

Aggiornamento: novembre 2007

In .NET Framework sono disponibili tre modalità per creare codice Microsoft Intermediate Language (MSIL), ognuna delle quali presenta problemi di sicurezza specifici:

  • Assembly dinamici

  • Metodi dinamici ospitati anonimamente

  • Metodi dinamici associati ad assembly esistenti

Indipendentemente dalla modalità di generazione del codice dinamico, l'esecuzione del codice generato richiede tutte le autorizzazioni necessarie per i tipi e i metodi utilizzati dallo stesso codice generato.

Nota:

Le autorizzazioni richieste per la riflessione sul codice e la creazione di codice sono state modificate nelle versioni successive di .NET Framework. Vedere Informazioni sulla versione più avanti in questo argomento.

Assembly dinamici

Gli assembly dinamici vengono creati utilizzando gli overload del metodo AppDomain.DefineDynamicAssembly. Le autorizzazioni richieste dipendono dall'overload utilizzato. Gli overload che forniscono evidenza, ad esempio, richiedono SecurityPermission con il flag SecurityPermissionFlag.ControlEvidence. Alcuni overload non richiedono autorizzazioni e possono essere chiamati da codice dotato solo di autorizzazioni Internet.

Il codice in un assembly dinamico può accedere a tipi e membri visibili in altri assembly.

Nota:

Gli assembly dinamici non utilizzano i flag ReflectionPermissionFlag.MemberAccess e ReflectionPermissionFlag.RestrictedMemberAccess che consentono ai metodi dinamici di accedere a tipi e membri non pubblici.

La generazione di codice con simboli di debug richiede ReflectionPermission con il flag ReflectionPermissionFlag.ReflectionEmit.

Gli assembly dinamici temporanei vengono creati in memoria e mai salvati su disco, pertanto non richiedono autorizzazioni di accesso ai file. Il salvataggio di un assembly dinamico su disco richiede FileIOPermission con i flag appropriati.

Generazione di assembly dinamici da codice parzialmente attendibile

Considerare le condizioni in cui un assembly con autorizzazioni Internet può generare un assembly dinamico temporaneo ed eseguire il rispettivo codice:

  • L'assembly dinamico utilizza solo tipi e membri pubblici di altri assembly.

  • Le autorizzazioni richieste da tali tipi e membri sono incluse nella concessione dell'assembly parzialmente attendibile.

  • L'overload del metodo DefineDynamicAssembly utilizzato per creare l'assembly dinamico non richiede autorizzazioni speciali, ovvero non viene fornita alcuna evidenza e così via.

  • L'assembly non viene salvato su disco.

  • I simboli di debug non vengono generati. I set di autorizzazioni Internet e LocalIntranet non includono il flag ReflectionPermissionFlag.ReflectionEmit.

Definizione di autorizzazioni per gli assembly dinamici

Nell'elenco seguente la funzione di emissione è l'assembly che genera l'assembly dinamico.

  • Una funzione di emissione che dispone di SecurityPermission con il flag SecurityPermissionFlag.ControlEvidence può fornire evidenza per il codice generato. Queste prove vengono mappate attraverso i criteri per determinare le autorizzazioni concesse.

  • Una funzione di emissione può fornire evidenza null e in questo caso l'assembly ottiene il set di autorizzazioni della funzione di emissione. In questo modo si garantisce che il codice generato non disponga di autorizzazioni maggiori della relativa funzione di emissione.

  • Se si forniscono set di autorizzazioni con SecurityAction.RequestMinimum, SecurityAction.RequestOptional o SecurityAction.RequestRefuse, tali set di autorizzazioni non verranno utilizzati finché l'assembly non viene salvato su disco, quindi caricato da disco.

  • Dopo il salvataggio di un assembly dinamico su disco, l'assembly viene gestito come qualsiasi altro assembly caricato da disco.

  • Il codice generato da funzioni di emissione semi-trusted viene sempre verificato. In particolare il runtime verifica sempre il codice che non dispone dell'autorizzazione SecurityPermission con il flag SecurityPermissionFlag.SkipVerification. Le funzioni di emissione completamente attendibili possono ignorare o richiedere la verifica del codice generato.

Metodi dinamici ospitati anonimamente

I metodi dinamici ospitati anonimamente vengono creati utilizzando i due costruttori DynamicMethod che non specificano un modulo o un tipo associato, DynamicMethod(String, Type, array<Type[]) e DynamicMethod(String, Type, array<Type[], Boolean). Questi costruttori inseriscono i metodi dinamici in un assembly SecurityTransparent completamente attendibile fornito dal sistema. Per utilizzare questi costruttori o per creare codice per i metodi dinamici non è richiesta alcuna autorizzazione.

Al contrario, quando si crea un metodo dinamico ospitato anonimamente, viene acquisito lo stack di chiamate. Quando il metodo viene costruito, le richieste di sicurezza vengono effettuate in base allo stack di chiamate acquisito.

Nota:

Dal punto di vista concettuale le richieste vengono effettuate durante la costruzione del metodo, ovvero potrebbero essere effettuate durante la generazione di ogni istruzione MSIL. Nell'implementazione corrente tutte le richieste vengono effettuate quando viene chiamato il metodo DynamicMethod.CreateDelegate o quando viene richiamato il compilatore JIT, se il metodo viene richiamato senza chiamare CreateDelegate.

I metodi dinamici ospitati anonimamente possono ignorare i controlli di visibilità JIT, salvo la restrizione seguente: i tipi e i membri non pubblici a cui accede un metodo dinamico ospitato anonimamente devono trovarsi in assembly le cui concessioni sono uguali o sono sottoinsiemi della concessione dello stack di chiamate che li genera. Questa limitata capacità di ignorare i controlli di visibilità JIT richiede ReflectionPermission con il flag ReflectionPermissionFlag.RestrictedMemberAccess.

  • Se il metodo utilizza solo tipi e membri pubblici, non è richiesta alcuna autorizzazione durante la costruzione.

  • Se si specifica che i controlli di visibilità di JIT debbano essere ignorati, la richiesta effettuata durante la costruzione del metodo includerà ReflectionPermission con il flag ReflectionPermissionFlag.RestrictedMemberAccess e la concessione dell'assembly che contiene il membro non pubblico a cui si accede.

Poiché viene presa in considerazione la concessione del membro non pubblico, il codice parzialmente attendibile a cui è stata concessa l'autorizzazione ReflectionPermissionFlag.RestrictedMemberAccess non può elevare i privilegi eseguendo membri non pubblici di assembly attendibili.

Come con qualsiasi altro codice generato, per l'esecuzione del metodo dinamico sono necessarie le autorizzazioni richieste dai metodi utilizzati dallo stesso metodo dinamico.

Per ulteriori informazioni, vedere la classe DynamicMethod.

Generazione di metodi dinamici ospitati anonimamente da codice parzialmente attendibile

Considerare le condizioni in cui un assembly con autorizzazioni Internet può generare un metodo dinamico ospitato anonimamente ed eseguirlo:

  • Il metodo dinamico utilizza solo tipi e membri pubblici. Se la relativa concessione include ReflectionPermissionFlag.RestrictedMemberAccess, può utilizzare tipi e membri non pubblici di qualsiasi assembly la cui concessione è uguale o è un sottoinsieme della concessione dell'assembly che li genera.

  • Le autorizzazioni richieste da tutti i tipi e membri utilizzati dal metodo dinamico sono incluse nella concessione dell'assembly parzialmente attendibile.

Nota:

I metodi dinamici non supportano i simboli di debug.

Metodi dinamici associati ad assembly esistenti

Per associare un metodo dinamico a un tipo o modulo in un assembly esistente, utilizzare uno dei costruttori DynamicMethod che specificano il tipo o il modulo associato. Le autorizzazioni richieste per chiamare questi costruttori variano, poiché l'associazione di un metodo dinamico a un tipo o modulo esistente consente al metodo dinamico di accedere a tipi e membri non pubblici:

  • Un metodo dinamico associato a un tipo può accedere a tutti i membri di quel tipo, anche ai membri privati, e a tutti i tipi e membri interni nell'assembly che contiene il tipo associato.

  • Un metodo dinamico associato a un modulo dispone dell'accesso a tutti i tipi e membri internal (Friend in Visual Basic, assembly nei metadati di Common Language Runtime) del modulo.

Inoltre è possibile utilizzare un costruttore che specifichi la possibilità da ignorare i controlli di visibilità del compilatore JIT. In questo modo il metodo dinamico potrà accedere a tutti i tipi e i membri in tutti gli assembly, indipendentemente dal livello di accesso.

Le autorizzazioni richieste dal costruttore dipendono dal livello di accesso che si sceglie di fornire al metodo dinamico.

Anche se gli elementi in questo elenco sono descritti in termini di concessione dell'assembly che li genera, ricordare che le richieste vengono effettuate sullo stack di chiamate completo, incluso il limite del dominio applicazione.

Per ulteriori informazioni, vedere la classe DynamicMethod.

Generazione di metodi dinamici da codice parzialmente attendibile

Nota:

La modalità consigliata per generare metodi dinamici da codice parzialmente attendibile consiste nell'utilizzare metodi dinamici ospitati anonimamente.

Considerare le condizioni in cui un assembly con autorizzazioni Internet può generare un metodo dinamico ed eseguirlo:

  • Il metodo dinamico è associato al modulo o al tipo che lo genera oppure la concessione include ReflectionPermissionFlag.RestrictedMemberAccess ed è associata a un modulo in un assembly la cui concessione è uguale o è un sottoinsieme della concessione dell'assembly che lo genera.

  • Il metodo dinamico utilizza solo tipi e membri pubblici. Se la concessione include ReflectionPermissionFlag.RestrictedMemberAccess ed è associata a un modulo in un assembly la cui concessione è uguale o è un sottoinsieme della concessione dell'assembly che lo genera, può utilizzare tipi e membri contrassegnati come internal (Friend in Visual Basic, assembly nei metadati di Common Language Runtime) nel modulo associato.

  • Le autorizzazioni richieste da tutti i tipi e i membri utilizzati dal metodo dinamico sono incluse nella concessione dell'assembly parzialmente attendibile.

  • Il metodo dinamico non ignora i controlli di visibilità JIT.

Nota:

I metodi dinamici non supportano i simboli di debug.

Informazioni sulla versione

A partire da .NET Framework 2.0 Service Pack 1 non è più richiesto ReflectionPermission con il flag ReflectionPermissionFlag.ReflectionEmit quando vengono generati assembly dinamici e metodi dinamici. Questo flag è richiesto in tutte le versioni precedenti di .NET Framework.

Nota:

ReflectionPermission con il flag ReflectionPermissionFlag.ReflectionEmit è incluso per impostazione predefinita nei set di autorizzazioni denominati FullTrust e LocalIntranet, ma non nel set di autorizzazioni Internet. Di conseguenza nelle versioni precedenti di .NET Framework una libreria può essere utilizzata con autorizzazioni Internet solo se esegue Assert per ReflectionEmit. Tali librerie richiedono un'accurata revisione della sicurezza perché eventuali errori nel codice potrebbero comportare problemi di sicurezza. .NET Framework 2.0 SP1 consente che il codice venga generato in scenari di attendibilità parziale senza emettere alcuna richiesta di sicurezza, perché la generazione di codice non è, per sua natura, un'operazione privilegiata. Ovvero, il codice generato non ha più autorizzazioni dell'assembly che lo genera. Questo consente alle librerie che generano il codice di essere SecurityTransparent ed elimina la necessità di utilizzare un'asserzione di ReflectionEmit, semplificando l'attività di scrittura di una libreria protetta.

Inoltre in .NET Framework 2.0 SP1 viene introdotto il flag ReflectionPermissionFlag.RestrictedMemberAccess per l'accesso ai tipi e ai membri non pubblici dai metodi dinamici parzialmente attendibili. Le versioni precedenti di .NET Framework richiedono il flag ReflectionPermissionFlag.MemberAccess per i metodi dinamici che accedono a tipi e membri non pubblici. Questa è un'autorizzazione che non dovrebbe mai essere concessa al codice parzialmente attendibile.

Infine in .NET Framework 2.0 SP1 vengono introdotti metodi ospitati anonimamente.

Per utilizzare queste funzionalità, l'applicazione deve essere indirizzata a .NET Framework versione 3.5. Per ulteriori informazioni, vedere Architettura di .NET Framework 3.5.

Recupero di informazioni su tipi e membri

A partire da .NET Framework 2.0 non sono richieste autorizzazioni per ottenere informazioni su tipi e membri non pubblici. La riflessione viene utilizzata per ottenere le informazioni necessarie a generare metodi dinamici. Ad esempio, gli oggetti MethodInfo vengono utilizzati per generare chiamate al metodo. Le versioni precedenti di .NET Framework richiedono ReflectionPermission con il flag ReflectionPermissionFlag.TypeInformation. Per ulteriori informazioni, vedere Considerazioni sulla sicurezza in relazione alla riflessione.

Vedere anche

Concetti

Considerazioni sulla sicurezza in relazione alla riflessione

Altre risorse

Creazione di assembly e metodi dinamici