Problemi di sicurezza nella reflection emit
.NET Framework offre tre modi per generare un linguaggio intermedio comune (CIL), ognuno con i propri problemi di sicurezza:
- Assembly dinamici
- Metodi dinamici ospitati in modo anonimo
- 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 usati dal codice generato.
Nota
Le autorizzazioni necessarie per la reflection sul codice e la creazione del codice sono state modificate nelle versioni successive di .NET Framework. Vedere Informazioni sulla versione più avanti in questo articolo.
Assembly dinamici
Gli assembly dinamici vengono creati usando gli overload del metodo AppDomain.DefineDynamicAssembly. La maggior parte di overload di questo metodo sono deprecati in .NET Framework 4 a causa dell'eliminazione dei criteri di sicurezza a livello di computer. Gli overload rimanenti possono essere eseguiti da qualsiasi codice, indipendentemente dal livello di attendibilità. Questi overload rientrano in due gruppi: quelli che specificano un elenco di attributi da applicare all'assembly dinamico quando viene creato e quelli che non lo specificano. Se non si specifica il modello di trasparenza per l'assembly, applicando l'attributo SecurityRulesAttribute durante la creazione, il modello di trasparenza viene ereditato dall'assembly di creazione.
Nota
Gli attributi applicati all'assembly dinamico dopo averlo creato mediante il metodo SetCustomAttribute non sono effettivi fino a quando l'assembly non viene salvato su disco e caricato di nuovo in memoria.
Il codice in un assembly dinamico può accedere a tipi e membri visibili in altri assembly.
Nota
Gli assembly dinamici non usano i flag ReflectionPermissionFlag.MemberAccess e ReflectionPermissionFlag.RestrictedMemberAccess che consentono ai metodi dinamici di accedere a tipi e membri non pubblici.
Gli assembly dinamici temporanei vengono creati in memoria e non vengono mai salvati su disco, pertanto non richiedono alcuna autorizzazione di accesso ai file. Il salvataggio di un assembly dinamico su disco richiede FileIOPermission con 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 eseguirne il codice:
L'assembly dinamico usa solo tipi e membri pubblici di altri assembly.
Le autorizzazioni richieste da questi tipi e membri sono incluse nel set di concessioni dell'assembly parzialmente attendibile.
L'assembly non viene salvato su disco.
I simboli di debug non vengono generati. I set di autorizzazioni
Internet
eLocalIntranet
non includono le autorizzazioni necessarie.
Metodi dinamici ospitati anonimamente
I metodi dinamici ospitati anonimamente vengono creati usando i due costruttori DynamicMethod che non specificano un tipo o un modulo associato, DynamicMethod(String, Type, Type[]) e DynamicMethod(String, Type, Type[], Boolean). Questi costruttori inseriscono i metodi dinamici in un assembly fornito dal sistema, completamente attendibile, trasparente per la sicurezza. Non sono necessarie autorizzazioni per usare questi costruttori o per generare il codice per i metodi dinamici.
Al contrario, quando viene creato un metodo dinamico ospitato anonimamente, viene acquisito lo stack di chiamate. Quando il metodo viene costruito, le richieste di sicurezza vengono effettuate sullo stack di chiamate acquisito.
Nota
Concettualmente, le richieste vengono effettuate durante la costruzione del metodo. Ciò significa che le richieste possono essere effettuate man mano che viene generata ogni istruzione CIL. Nell'implementazione corrente tutte le richieste vengono effettuate quando il metodo DynamicMethod.CreateDelegate viene chiamato o quando viene richiamato il compilatore Just-In-Time (JIT), se il metodo viene richiamato senza chiamare CreateDelegate.
Se il dominio applicazione lo consente, i metodi dinamici ospitati anonimamente possono ignorare i controlli di visibilità JIT, ma solo se viene rispettata la restrizione seguente: i tipi e i membri non pubblici a cui accede un metodo dinamico ospitato anonimamente devono trovarsi in assembly i cui set di concessioni sono uguali o sono subset del set di concessioni dello stack di chiamate di creazione. Questa possibilità limitata di ignorare i controlli di visibilità JIT viene abilitata se il dominio applicazione concede ReflectionPermission con il flag ReflectionPermissionFlag.RestrictedMemberAccess.
Se il metodo usa solo tipi e membri pubblici, non sono necessarie autorizzazioni durante la costruzione.
Se si specifica che i controlli di visibilità JIT debbano essere ignorati, la richiesta effettuata durante la costruzione del metodo includerà ReflectionPermission con il flag ReflectionPermissionFlag.RestrictedMemberAccess e il set di concessioni dell'assembly che contiene il membro non pubblico a cui si accede.
Poiché il set di concessioni del membro non pubblico viene preso in considerazione, il codice parzialmente attendibile che ha ottenuto ReflectionPermissionFlag.RestrictedMemberAccess non può elevare i privilegi eseguendo membri non pubblici di assembly attendibili.
Come con qualsiasi altro codice generato, l'esecuzione del metodo dinamico richiede le autorizzazioni obbligatorie per i metodi usate dal metodo dinamico.
L'assembly di sistema che ospita i metodi dinamici ospitati in modo anonimo usa il modello di trasparenza SecurityRuleSet.Level1, che è stato usato in .NET Framework prima di .NET Framework 4.
Per altre informazioni, vedere la classe DynamicMethod.
Generazione di metodi dinamici ospitati anonimamente dal 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 usa solo tipi e membri pubblici. Se il set di concessioni include ReflectionPermissionFlag.RestrictedMemberAccess, è possibile usare i tipi e i membri non pubblici di qualsiasi assembly il cui set di concessioni sia uguale o sia un subset del set di concessioni dell'assembly di creazione.
Le autorizzazioni necessarie per tutti i tipi e i membri usati dal metodo dinamico sono incluse nel set di concessioni 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 a un modulo in un assembly esistente, usare uno qualsiasi dei costruttori DynamicMethod che specificano il tipo o il modulo associato. Le autorizzazioni necessarie per chiamare questi costruttori variano, poiché l'associazione di un metodo dinamico a un tipo o a un modulo esistente fornisce al metodo dinamico l'accesso ai membri e ai tipi non pubblici:
Un metodo dinamico associato a un tipo può accedere a tutti i membri di tale 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 può accedere a tutti i tipi e membri di
internal
(Friend
in Visual Basic,assembly
nei metadati di Common Language Runtime) nel modulo.
Inoltre, è possibile usare un costruttore che consente di specificare la possibilità di ignorare i controlli di visibilità del compilatore JIT. In questo modo il metodo dinamico può accedere a tutti i tipi e membri in tutti gli assembly, indipendentemente dal livello di accesso.
Le autorizzazioni richieste dal costruttore dipendono dal livello di accesso che si decide di concedere al metodo dinamico:
Se il metodo usa solo membri e tipi pubblici e lo si associa a un tipo o a un modulo personalizzato, non sono necessarie autorizzazioni.
Se si specifica che devono essere ignorati i controlli di visibilità JIT, il costruttore richiede ReflectionPermission con il flag ReflectionPermissionFlag.MemberAccess.
Se si associa il metodo dinamico a un altro tipo, anche all'interno dell'assembly, il costruttore richiede ReflectionPermission con il flag ReflectionPermissionFlag.MemberAccess e SecurityPermission con il flag SecurityPermissionFlag.ControlEvidence.
Se si associa il metodo dinamico a un tipo o a un modulo in un altro assembly, il costruttore richiede due cose: ReflectionPermission con il flag ReflectionPermissionFlag.RestrictedMemberAccess e il set di concessioni dell'assembly che contiene l'altro modulo. Ovvero, lo stack di chiamate deve includere tutte le autorizzazioni nel set di concessioni del modulo di destinazione, oltre a ReflectionPermissionFlag.RestrictedMemberAccess.
Nota
Per la compatibilità con le versioni precedenti, se la richiesta per il set di concessioni di destinazione con ReflectionPermissionFlag.RestrictedMemberAccess ha esito negativo, il costruttore richiede SecurityPermission con il flag SecurityPermissionFlag.ControlEvidence.
Anche se gli elementi nell'elenco vengono descritti in termini di set di concessioni dell'assembly, tenere presente che le richieste vengono effettuate sullo stack di chiamate completo, incluso il limite del dominio applicazione.
Per altre informazioni, vedere la classe DynamicMethod.
Generazione di metodi dinamici dal codice parzialmente attendibile
Nota
Il modo consigliato per generare metodi dinamici da codice parzialmente attendibile consiste nell'usare metodi dinamici ospitati in modo anonimo.
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 il set di concessioni include ReflectionPermissionFlag.RestrictedMemberAccess ed è associato a un modulo in un assembly il cui set di concessioni è uguale o è un subset del set di concessioni dell'assembly di creazione.
Il metodo dinamico usa solo tipi e membri pubblici. Se il set di concessioni include ReflectionPermissionFlag.RestrictedMemberAccess ed è associato a un modulo in un assembly il cui set di concessioni è uguale o è un subset del set di concessioni dell'assembly di creazione, può usare 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 usati dal metodo dinamico sono inclusi nel set di concessioni 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 4, i criteri di sicurezza a livello di computer sono eliminati e la trasparenza della sicurezza diventa il meccanismo di imposizione predefinito.
A partire da .NET Framework 2.0 Service Pack 1, quando si generano assembly e metodi dinamici non è più necessario usare ReflectionPermission con il flag ReflectionPermissionFlag.ReflectionEmit. Questo flag è richiesto in tutte le versioni precedenti di .NET Framework.
Nota
ReflectionPermission con il flag ReflectionPermissionFlag.ReflectionEmit viene incluso per impostazione predefinita nei set di autorizzazioni denominati FullTrust
e LocalIntranet
, ma non nel set di autorizzazioni Internet
. Pertanto, nelle versioni precedenti di .NET Framework è possibile usare una libreria con autorizzazioni Internet solo se viene eseguito un Assert per ReflectionEmit. Tali librerie richiedono un'attenta revisione della sicurezza perché eventuali errori nel codice potrebbe produrre delle vulnerabilità. .NET Framework 2.0 SP1 consente di generare codice in scenari con attendibilità parziale senza creare alcuna richiesta di sicurezza, poiché la generazione di codice non è implicitamente un'operazione con privilegi. Ovvero, il codice generato non dispone di ulteriori autorizzazioni rispetto all'assembly che lo genera. Questo consente alle librerie che generano il codice di essere SecurityTransparent ed elimina la necessità di asserire ReflectionEmit, che semplifica l'attività di scrittura di una libreria protetta.
.NET Framework 2.0 SP1 introduce inoltre il flag ReflectionPermissionFlag.RestrictedMemberAccess per l'accesso a tipi e membri non pubblici da metodi dinamici parzialmente attendibili. Le versioni precedenti di .NET Framework richiedono il flag ReflectionPermissionFlag.MemberAccess per i metodi dinamici che accedono a membri e tipi non pubblici; si tratta di un'autorizzazione che non dovrebbe mai essere concessa a codice parzialmente attendibile.
Infine .NET Framework 2.0 SP1 introduce i metodi ospitati in modo anonimo.
Informazioni su tipi e membri
A partire da .NET Framework 2.0 non sono necessarie autorizzazioni per ottenere informazioni su tipi e membri non pubblici. Per ottenere le informazioni necessarie a generare metodi dinamici viene usato Reflection. Ad esempio, gli oggetti MethodInfo vengono usati per generare le chiamate al metodo. Le versioni precedenti di .NET Framework richiedono ReflectionPermission con il flag ReflectionPermissionFlag.TypeInformation. Per altre informazioni, vedere Security Considerations for Reflection (Considerazioni sulla sicurezza per reflection).
Vedi anche
- Security Considerations for Reflection (Considerazioni sulla sicurezza per reflection)
- Creazione di assembly e metodi dinamici