Modifiche della sicurezza in .NET Framework 4

In .NET Framework versione 4 sono state apportate due importanti modifiche alla sicurezza. I criteri di sicurezza a livello di computer sono stati eliminati, anche se il sistema delle autorizzazioni è rimasto, e la trasparenza della sicurezza è diventata il meccanismo di imposizione predefinito. Per ulteriori informazioni, vedere Codice SecurityTransparent, livello 2. Inoltre, alcune operazioni con autorizzazioni che potevano presentare vulnerabilità per la sicurezza sono state rese obsolete.

Nota importanteImportante

Non è stata eliminata la sicurezza dall'accesso di codice (CAS, Code Access Security), ma sono stati eliminati i criteri di sicurezza dal modello CAS. L'evidenza e le autorizzazioni sono ancora valide.Sono state eliminate alcune autorizzazioni e la trasparenza ha semplificato l'imposizione della sicurezza.Per alcuni cenni preliminari sulle modifiche, vedere Riepilogo delle modifiche alla sicurezza dall'accesso di codice.

È opportuno tenere conto dei seguenti fattori:

  • La trasparenza separa il codice che viene eseguito come parte dell'applicazione dal codice eseguito come parte dell'infrastruttura. È stata introdotta in .NET Framework versione 2.0 ed è stata migliorata per diventare il meccanismo di imposizione della sicurezza dall'accesso di codice. A differenza dei criteri di sicurezza, le regole di trasparenza di livello 2 vengono applicate in fase di esecuzione, non durante il caricamento dell'assembly. Queste regole sono sempre attive, anche per gli assembly in esecuzione con attendibilità totale per impostazione predefinita. La trasparenza di livello 2 non influisce tuttavia sul codice completamente attendibile non annotato, ad esempio le applicazioni desktop. Gli assembly, inclusi gli assembly desktop, contrassegnati con SecurityTransparentAttribute e che chiamano metodi contrassegnati con SecurityCriticalAttribute ricevono un'eccezione MethodAccessException. È possibile modificare tale comportamento applicando SecurityRulesAttribute e impostando la proprietà SecurityRulesAttribute.RuleSet su Level1. È tuttavia, consigliabile eseguire questa operazione solo per garantire la compatibilità con le versioni precedenti. È necessario contrassegnare in modo esplicito un'applicazione desktop come SecurityTransparent per applicarvi le restrizioni di trasparenza.

  • Il codice che chiama le API dei criteri di sicurezza riceve un'eccezione NotSupportedException oltre agli avvisi del compilatore in fase di esecuzione. I criteri possono essere riabilitati tramite l'elemento di configurazione <NetFx40_LegacySecurityPolicy>. Quando i criteri sono abilitati, la trasparenza della sicurezza viene comunque applicata. I criteri di sicurezza vengono applicati durante il caricamento dell'assembly e non hanno effetto sulla trasparenza, che viene applicata in fase di esecuzione.

  • Le autorizzazioni di richiesta obsolete (RequestMinimum, RequestOptional e RequestRefuse) ricevono avvisi del compilatore e non funzionano in .NET Framework 4, ma non provocano la generazione di un'eccezione. Le richieste Deny provocano la generazione di un'eccezione NotSupportedException in fase di esecuzione.

  • L'azione di sicurezza LinkDemand non è obsoleta, ma non deve essere utilizzata per la verifica delle autorizzazioni. Utilizzare invece SecurityCriticalAttribute per i tipi e i metodi che richiedono l'attendibilità totale o utilizzare il metodo Demand per i tipi e i metodi che richiedono singole autorizzazioni.

  • Se l'applicazione viene compilata con Visual Studio 2010, è possibile eseguirla senza queste modifiche specificando una versione di .NET Framework di destinazione precedente rispetto a .NET Framework 4 nelle impostazioni del progetto di Visual Studio. Non sarà tuttavia possibile utilizzare i nuovi tipi e membri di .NET Framework 4. È inoltre possibile specificare una versione precedente di .NET Framework tramite l'elemento <supportedRuntime> nello schema delle impostazioni di avvio del file di configurazione dell'applicazione.

Nelle sezioni seguenti vengono descritte queste e altre modifiche introdotte in .NET Framework 4. 

  • Semplificazione dei criteri di sicurezza

  • Livello 2 di trasparenza della sicurezza

  • Richieste di autorizzazioni obsolete

  • APTCA condizionale

  • Oggetti di evidenza

  • Insiemi di evidenze

Semplificazione dei criteri di sicurezza

A partire da .NET Framework 4, Common Language Runtime non fornisce più criteri di sicurezza per i computer. In passato, .NET Framework forniva i criteri di sicurezza dall'accesso di codice come meccanismo per controllare e configurare con precisione le funzionalità del codice gestito. Anche se l'utilizzo dei criteri di sicurezza dall'accesso di codice è efficace, può risultare complicato e restrittivo. Inoltre, i criteri di sicurezza dall'accesso di codice non si applicano alle applicazioni native, pertanto le garanzie di sicurezza risultano limitate. Gli amministratori di sistema dovrebbero optare per soluzioni a livello di sistema operativo quali i criteri di restrizione software Windows o AppLocker in Windows 7 e Windows Server 2008 R2 come funzionalità sostitutive per i criteri di sicurezza dall'accesso di codice. I criteri di restrizione software Windows e AppLocker forniscono meccanismi attendibili semplici che si applicano al codice gestito e nativo. Come soluzione di sicurezza, i criteri di restrizione software Windows e AppLocker sono più semplici e forniscono migliori garanzie rispetto ai criteri di sicurezza dall'accesso di codice.

In .NET Framework 4, i criteri di sicurezza a livello di computer sono disattivati per impostazione predefinita. Le applicazioni non ospitate, ovvero le applicazioni eseguite tramite Esplora risorse o dal prompt dei comandi, vengono ora eseguite con attendibilità totale. Sono incluse tutte le applicazioni che si trovano in condivisioni sulla rete locale. Le applicazioni ospitate o sandbox continuano a essere eseguite con criteri di attendibilità stabiliti dai relativi host, ad esempio da Internet Explorer, ClickOnce o ASP.NET. Le applicazioni o i controlli eseguiti in sandbox sono considerati parzialmente attendibili.

Per semplificare i criteri di sicurezza, a .NET Framework è stato applicato il modello di trasparenza. Le applicazioni e i controlli eseguiti in un host o in un sandbox con il set di autorizzazioni limitato concesso dal sandbox sono considerate trasparenti. La trasparenza indica che non è necessario controllare i criteri di sicurezza dall'accesso di codice quando si eseguono applicazioni parzialmente attendibili. Le applicazioni trasparenti vengono eseguite solo utilizzando la relativa concessione. Il programmatore deve semplicemente scrivere applicazioni destinate alla concessione per il relativo sandbox e che non chiamano codice che richiede l'attendibilità totale (codice SecurityCritical).

Nota importanteImportante

Come conseguenza di queste modifiche dei criteri di sicurezza potrebbero verificarsi avvisi di compilazione ed eccezioni in fase di esecuzione se si chiamano i membri e i tipi dei criteri di sicurezza dall'accesso di codice obsoleti in modo esplicito o implicito (tramite altri tipi e membri).Per un elenco dei tipi e dei membri obsoleti e delle relative sostituzioni, vedere Migrazione e compatibilità dei criteri di sicurezza dall'accesso di codice.

È possibile evitare gli avvisi e gli errori utilizzando l'elemento di configurazione <NetFx40_LegacySecurityPolicy> nello schema delle impostazioni dell'ambiente di esecuzione per consentire esplicitamente il comportamento dei criteri di sicurezza dall'accesso di codice legacy.Tuttavia, la specifica dell'utilizzo di criteri di sicurezza legacy non include criteri di sicurezza dall'accesso di codice personalizzati per quella versione, a meno che non venga eseguita la migrazione a .NET Framework 4.

È inoltre possibile abilitare i criteri di sicurezza dall'accesso di codice legacy impostando la versione di .NET Framework di destinazione per il progetto di Visual Studio su una versione precedente rispetto a .NET Framework 4. In tal modo i criteri di sicurezza dall'accesso di codice legacy vengono abilitati e vengono inclusi i criteri di sicurezza dall'accesso di codice personalizzati specificati per tale versione.Non sarà tuttavia possibile utilizzare i nuovi tipi e membri di .NET Framework 4.È inoltre possibile specificare una versione precedente di .NET Framework tramite l'elemento <supportedRuntime> nello schema delle impostazioni di avvio.

Torna all'inizio

Livello 2 di trasparenza della sicurezza

La trasparenza della sicurezza è stata introdotta in .NET Framework versione 2.0, ma in modo molto limitato e principalmente per migliorare l'efficienza di convalida del codice. In .NET Framework 4, la trasparenza è un meccanismo di imposizione che separa il codice che viene eseguito come parte dell'applicazione dal codice eseguito come parte dell'infrastruttura. La trasparenza consente di creare una barriera tra il codice autorizzato a eseguire operazioni privilegiate (codice Critical), ad esempio chiamare codice nativo, e il codice che non dispone di tale autorizzazione (codice Transparent). Il codice trasparente può eseguire comandi all'interno dei limiti del set di autorizzazioni in cui sta funzionando, ma non può eseguire, chiamare, derivare o contenere codice critico.

L'obiettivo principale dell'imposizione della trasparenza è fornire un meccanismo semplice e valido per isolare gruppi diversi di codice in base ai privilegi. Nel modello di sandboxing, questi gruppi di privilegi sono completamente attendibili (non limitati) o parzialmente attendibili (limitati al set di autorizzazioni concesso al sandbox).

Le applicazioni desktop vengono eseguite con attendibilità totale e non sono pertanto interessate dal modello di trasparenza. Per ulteriori informazioni sulle modifiche apportate alla trasparenza della sicurezza, vedere Codice SecurityTransparent, livello 2.

Torna all'inizio

Richieste di autorizzazioni obsolete

Il supporto del runtime è stato rimosso per l'imposizione delle richieste di autorizzazioni Deny, RequestMinimum, RequestOptional e RequestRefuse. In generale, queste richieste non venivano interpretate correttamente e potevano provocare vulnerabilità della sicurezza se non utilizzate in modo adeguato:

  • Risultava semplice eseguire l'override di un'azione Deny con un'azione Assert. Il codice di un assembly era in grado di eseguire un'azione Assert per un'autorizzazione se l'autorizzazione rientrava nella concessione per l'assembly. Assert impediva il rilevamento di un'azione Deny sullo stack, rendendola inefficace.

  • La richiesta RequestMinimum non poteva essere utilizzata in modo efficace fuori dall'ambito dell'applicazione. Se RequestMinimum era presente in un file eseguibile (con estensione exe) e la concessione non veniva soddisfatta, gli utenti finali del file ricevevano un'eccezione FileLoadException non gestita senza informazioni sulla correzione del problema. Non era possibile utilizzare un set di richiesta minimo per le librerie (file dll), perché tipi e membri diversi nell'assembly generalmente dispongono di requisiti di autorizzazione diversi.

  • La richiesta RequestOptional risultava poco chiara e spesso veniva utilizzata erroneamente con risultati imprevisti. Gli sviluppatori potevano omettere facilmente autorizzazioni dall'elenco senza rendersi conto che facendo così rifiutavano in modo implicito le autorizzazioni omesse.

  • RequestRefuse non forniva un modello con privilegi più bassi valido, perché richiedeva l'identificazione esplicita delle autorizzazioni non desiderate anziché di quelle necessarie. Le nuove autorizzazioni disponibili non venivano incluse nell'elenco. Il rifiuto non aveva inoltre senso per tutte le autorizzazioni. Ad esempio, era possibile rifiutare un valore per la proprietà UserQuota in IsolatedStoragePermission.

    Infine, specificando solo le autorizzazioni non desiderate si creava la possibilità di vulnerabilità della sicurezza nel caso in cui non fosse stato possibile identificare tutte le autorizzazioni potenzialmente dannose.

  • RequestOptional e RequestRefuse consentivano agli sviluppatori di interrompere i domini omogenei creando più set di autorizzazioni all'interno del dominio.

In .NET Framework 4 l'imposizione in fase di esecuzione di questi valori di enumerazione è stata rimossa. Gli assembly contenenti gli attributi che utilizzano questi valori SecurityAction continueranno a essere caricati. CLR non rifiuterà tuttavia di caricare gli assembly a cui viene fatto riferimento o di modificare la concessione di tali assembly in base ai set di autorizzazioni.

Torna all'inizio

APTCA condizionale

L'utilizzo condizionale dell'attributo AllowPartiallyTrustedCallersAttribute (APTCA) consente agli host di identificare quali assembly possono essere esposti ai chiamanti parzialmente attendibili caricati nel contesto dell'host. Gli assembly del candidato devono già essere progettati per l'attendibilità parziale, ovvero, devono essere di tipo APTCA (SecuritySafeCritical nel modello di trasparenza) o completamente trasparenti. Un nuovo costruttore per la classe AllowPartiallyTrustedCallersAttribute consente all'host di specificare il livello di visibilità per un assembly APTCA utilizzando l'enumerazione PartialTrustVisibilityLevel nella chiamata del costruttore.

Torna all'inizio

Oggetti di evidenza

Prima di .NET Framework 4, quasi tutti gli oggetti potevano essere utilizzati come oggetti di evidenza se il codice di hosting li applicava come tali. Ad esempio, parte del codice di .NET Framework riconosceva gli oggetti System.Uri come evidenze. Il runtime considerava gli oggetti di evidenza come riferimenti a System.Object e non vi applicava l'indipendenza dai tipi.

Questo comportamento presentava un problema perché .NET Framework imponeva restrizioni implicite sui tipi che era possibile utilizzare come oggetti di evidenza. In particolare, tutti gli oggetti utilizzati come evidenza dovevano essere serializzabili e non potevano essere null. Se questi requisiti non venivano soddisfatti, CLR generava un'eccezione ogni volta che veniva eseguita un'operazione che richiedeva uno di questi presupposti.

Per abilitare vincoli sui tipi di oggetti che è possibile utilizzare come evidenza e per consentire di aggiungere nuove funzionalità e nuovi requisiti a tutti gli oggetti di evidenza, in .NET Framework 4 è stata introdotta una nuova classe di base, System.Security.Policy.EvidenceBase, da cui devono derivare tutti gli oggetti di evidenza. La classe EvidenceBase assicura, tramite creazione di un'istanza, che l'oggetto di evidenza sia serializzabile. È inoltre possibile creare nuovi requisiti di evidenza in futuro aggiungendo nuove implementazioni predefinite alla classe di base.

Compatibilità con le versioni precedenti

Tutti i tipi utilizzati con CLR come oggetti di evidenza sono stati aggiornati in .NET Framework 4 in modo che derivino da EvidenceBase. I tipi di evidenza personalizzati utilizzati da applicazioni di terze parti non risultano tuttavia noti e non possono essere aggiornati. È pertanto impossibile utilizzare tali tipi di evidenza con i nuovi membri che presuppongono che le evidenze siano derivate da EvidenceBase.

Torna all'inizio

Insiemi di evidenze

Prima di .NET Framework 4, CLR generava il set completo di oggetti di evidenza validi per un assembly durante il caricamento dell'assembly. Tali oggetti venivano archiviati in un elenco che i consumer scorrevano per cercare un oggetto specifico. Tutte le evidenze venivano pertanto rese disponibili, indipendentemente dal fatto che venissero utilizzate. Per la maggior parte degli oggetti di evidenza questo comportamento non è un problema, tuttavia per gli oggetti di evidenza come System.Security.Policy.Publisher, che richiede la verifica Authenticode, questo meccanismo non è efficiente.

Per migliorare questo comportamento, l'interazione con l'insieme delle evidenze è stata riprogettata in .NET Framework 4. Un insieme di evidenze funziona ora come un dizionario anziché come un elenco. Anziché scorrere l'elenco delle evidenze per verificare se un oggetto di evidenza necessario esiste, i consumer possono ora richiedere un tipo specifico di evidenza e l'insieme restituirà l'evidenza, se trovata. Ad esempio, la chiamata StrongName name = evidence.GetHostEvidence<StrongName>(); restituisce un oggetto StrongName, se esistente; in caso contrario, restituisce null.

Questo modello di dizionario rimanda la generazione degli oggetti di evidenza al momento in cui vengono richiesti. Nell'esempio di evidenza di Publisher, il sovraccarico delle prestazioni derivante dalla verifica della firma Authenticode di un assembly viene rimandato al momento in cui tali informazioni sono effettivamente necessarie. Nel caso più comune di applicazioni con attendibilità totale, in cui non è necessaria l'evidenza Publisher, il processo di verifica viene evitato del tutto.

Torna all'inizio

Vedere anche

Concetti

Codice SecurityTransparent

Codice SecurityTransparent, livello 2

Migrazione e compatibilità dei criteri di sicurezza dall'accesso di codice