Nozioni fondamentali sulla sicurezza per l’accesso al codiceCode Access Security Basics

Attenzione

Sicurezza dall'accesso di codice e codice parzialmente attendibileCode Access Security and Partially Trusted Code

.NET Framework fornisce un meccanismo denominato sicurezza dall'accesso di codice, che consente di applicare vari livelli di attendibilità a codice diverso in esecuzione nella stessa applicazione.The .NET Framework provides a mechanism for the enforcement of varying levels of trust on different code running in the same application called Code Access Security (CAS). La sicurezza per l'accesso di codice in .NET Framework non deve essere usata come meccanismo per l'applicazione dei limiti di sicurezza in base alla creazione di codice o altri aspetti di identità.Code Access Security in .NET Framework should not be used as a mechanism for enforcing security boundaries based on code origination or other identity aspects. Le linee guida sono state modificate per specificare che la sicurezza per l'accesso di codice e il codice SecurityTransparent non saranno supportati come limiti di sicurezza con codice parzialmente attendibile, soprattutto nel caso di codice di origine sconosciuta.We are updating our guidance to reflect that Code Access Security and Security-Transparent Code will not be supported as a security boundary with partially trusted code, especially code of unknown origin. Non è consigliabile caricare ed eseguire codice di origine sconosciuta in assenza di misure di sicurezza alternative.We advise against loading and executing code of unknown origins without putting alternative security measures in place.

Questi criteri si applicano a tutte le versioni di .NET Framework, ma non alla versione di .NET Framework inclusa in Silverlight.This policy applies to all versions of .NET Framework, but does not apply to the .NET Framework included in Silverlight.

È necessario che tutte le applicazioni basate su Common Language Runtime, ovvero tutte le applicazioni gestite, interagiscano con il relativo sistema di sicurezza.Every application that targets the common language runtime (that is, every managed application) must interact with the runtime's security system. Quando un'applicazione gestita viene caricata, il relativo host concede automaticamente un set di autorizzazioni a tale applicazione.When a managed application is loaded, its host automatically grants it a set of permissions. Queste autorizzazioni sono determinate dalle impostazioni di sicurezza locali dell'host o dalla sandbox che contiene l'applicazione.These permissions are determined by the host's local security settings or by the sandbox the application is in. A seconda delle autorizzazioni, l'applicazione viene eseguita correttamente o genera un'eccezione di sicurezza.Depending on these permissions, the application either runs properly or generates a security exception.

L'host predefinito per le applicazioni desktop consente l'esecuzione del codice in modalità di attendibilità totale.The default host for desktop applications allows code to run in full trust. Se pertanto l'applicazione è destinata al desktop, dispone di un set di autorizzazione senza restrizioni.Therefore, if your application targets the desktop, it has an unrestricted permission set. Altri host o sandbox forniscono un set di autorizzazioni limitato per le applicazioni.Other hosts or sandboxes provide a limited permission set for applications. Poiché il set di autorizzazioni può essere diverso da host a host, è necessario progettare l'applicazione in modo che usi solo le autorizzazioni consentite dall'host di destinazione.Because the permission set can change from host to host, you must design your application to use only the permissions that your target host allows.

È necessario avere familiarità con i concetti attinenti alla sicurezza dall'accesso di codice, illustrati di seguito, per poter scrivere applicazioni efficienti basate su Common Language Runtime:You must be familiar with the following code access security concepts in order to write effective applications that target the common language runtime:

  • Codice indipendentedai tipi : il codice indipendente dai tipi è codice che accede ai tipi solo in modi ben definiti e consentiti.Type-safe code: Type-safe code is code that accesses types only in well-defined, allowable ways. Dato un riferimento a un oggetto valido, ad esempio, il codice indipendente dai tipi può accedere solo a offset fissi corrispondenti ai membri di campo effettivi.For example, given a valid object reference, type-safe code can access memory at fixed offsets that correspond to actual field members. Se tuttavia il codice accede alla memoria a offset arbitrari esterni all'intervallo di memoria appartenente ai campi dell'oggetto esposti in modo pubblico, non sarà indipendente dai tipi.If the code accesses memory at arbitrary offsets outside the range of memory that belongs to that object's publicly exposed fields, it is not type-safe. Per consentire al codice di usufruire dei vantaggi della sicurezza per l'accesso al codice, è necessario usare un compilatore che generi codice indipendente dai tipi verificabile.To enable code to benefit from code access security, you must use a compiler that generates verifiably type-safe code. Per ulteriori informazioni, vedere la sezione Scrittura di codice indipendente dai tipi verificabile più avanti in questo argomento.For more information, see the Writing Verifiably Type-Safe Code section later in this topic.

  • Sintassi imperativa e dichiarativa: il codice destinato a Common Language Runtime può interagire con il sistema di sicurezza richiedendo autorizzazioni, richiedendo che i chiamanti dispongano di autorizzazioni specificate ed eseguendo l'override di determinate impostazioni di sicurezza (con privilegi sufficienti).Imperative and declarative syntax: Code that targets the common language runtime can interact with the security system by requesting permissions, demanding that callers have specified permissions, and overriding certain security settings (given enough privileges). Per interagire a livello di codice con il sistema di sicurezza di .NET Framework, è necessario usare due forme differenti di sintassi: la sintassi dichiarativa e la sintassi imperativa.You use two forms of syntax to programmatically interact with the .NET Framework security system: declarative syntax and imperative syntax. Le chiamate dichiarative sono eseguite mediante l'impiego di attributi, le chiamate imperative mediante l'uso di nuove istanze di classi all'interno del codice.Declarative calls are performed using attributes; imperative calls are performed using new instances of classes within your code. Alcune chiamate possono essere eseguite solo in modo imperativo, altre solo in modo dichiarativo e altre ancora in nessun modo.Some calls can be performed only imperatively, others can be performed only declaratively, and some calls can be performed in either manner.

  • Libreriedi classi sicure : Una libreria di classi protetta utilizza richieste di sicurezza per garantire che i chiamanti della libreria dispongano dell'autorizzazione per accedere alle risorse esposte dalla libreria.Secure class libraries: A secure class library uses security demands to ensure that the library's callers have permission to access the resources that the library exposes. Una libreria di classi protetta potrebbe ad esempio usare un metodo per la creazione di file mediante il quale si impone che i chiamanti dispongano di specifiche autorizzazioni per creare file.For example, a secure class library might have a method for creating files that would demand that its callers have permissions to create files. In .NET Framework sono disponibili librerie di classi protette.The .NET Framework consists of secure class libraries. È necessario conoscere esattamente le autorizzazioni necessarie per l'accesso a ognuna delle librerie usate dal codice.You should be aware of the permissions required to access any library that your code uses. Per ulteriori informazioni, vedere la sezione Utilizzo di librerie di classi protette più avanti in questo argomento.For more information, see the Using Secure Class Libraries section later in this topic.

  • Codice trasparente: a partire da .NET Framework 4.NET Framework 4, oltre a identificare autorizzazioni specifiche, è necessario determinare se il codice deve essere eseguito come SecurityTransparent.Transparent code: Starting with the .NET Framework 4, in addition to identifying specific permissions, you must also determine whether your code should run as security-transparent. Il codice SecurityTransparent non può chiamare tipi o membri identificati come SecurityCritical.Security-transparent code cannot call types or members that are identified as security-critical. Questa regola si applica sia alle applicazioni completamente attendibili che a quelle parzialmente attendibili.This rule applies to full-trust applications as well as partially trusted applications. Per ulteriori informazioni, consultate Codice Security-Transparent.For more information, see Security-Transparent Code.

Scrittura di codice indipendente dai tipi verificabileWriting Verifiably Type-Safe Code

Durante la compilazione JIT viene eseguito un processo di verifica, in base al quale il codice viene esaminato, per provare a determinare se è indipendente dai tipi.Just-in-time (JIT) compilation performs a verification process that examines code and tries to determine whether the code is type-safe. Il codice che viene dimostrato durante la verifica come indipendente dai tipi viene chiamato codice indipendente dai tipi verificabile.Code that is proven during verification to be type-safe is called verifiably type-safe code. Esiste, infatti, codice che pur essendo indipendente dai tipi non è indipendente dai tipi verificabile, a causa delle limitazioni del processo di verifica o del compilatore.Code can be type-safe, yet might not be verifiably type-safe because of the limitations of the verification process or of the compiler. Non tutti i linguaggi sono indipendenti dai tipi e alcuni compilatori di linguaggio, quali Microsoft Visual C++, non sono in grado di generare codice gestito indipendente dai tipi verificabile.Not all languages are type-safe, and some language compilers, such as Microsoft Visual C++, cannot generate verifiably type-safe managed code. Per stabilire se il compilatore di linguaggio usato è in grado di generare codice indipendente dai tipi verificabile, consultare la documentazione del compilatore.To determine whether the language compiler you use generates verifiably type-safe code, consult the compiler's documentation. Se si utilizza un compilatore di linguaggio che genera codice indipendente dai tipi verificabile solo quando si evitano determinati costrutti di linguaggio, è possibile utilizzare lo strumento PEVerify per determinare se il codice è indipendente dai tipi verificabile.If you use a language compiler that generates verifiably type-safe code only when you avoid certain language constructs, you might want to use the PEVerify tool to determine whether your code is verifiably type-safe.

È tuttavia possibile tentare l'esecuzione di codice non indipendente dai tipi verificabile, se i criteri di sicurezza consentono al codice di evitare la verifica.Code that is not verifiably type-safe can attempt to execute if security policy allows the code to bypass verification. Poiché l'indipendenza dai tipi è tuttavia una componente essenziale del meccanismo di isolamento degli assembly nell'ambiente di esecuzione, non è possibile applicare la sicurezza in maniera affidabile se il codice viola le regole dell'indipendenza dai tipi.However, because type safety is an essential part of the runtime's mechanism for isolating assemblies, security cannot be reliably enforced if code violates the rules of type safety. In base all'impostazione predefinita, l'esecuzione del codice non indipendente dai tipi è consentita solo se il codice ha origine nel computer locale.By default, code that is not type-safe is allowed to run only if it originates from the local computer. È quindi necessario che il codice mobile sia indipendente dai tipi.Therefore, mobile code should be type-safe.

Uso di librerie di classi protetteUsing Secure Class Libraries

Se il codice richiede e ottiene le autorizzazioni richieste dalla libreria di classi, sarà autorizzato ad accedere alla libreria e le risorse esposte dalla libreria saranno protette dall'accesso non autorizzato.If your code requests and is granted the permissions required by the class library, it will be allowed to access the library and the resources that the library exposes will be protected from unauthorized access. Se il codice non dispone delle autorizzazioni appropriate, non sarà consentito l'accesso alla libreria di classi e il codice dannoso non potrà usare il codice dell'utente per accedere indirettamente alle risorse protette.If your code does not have the appropriate permissions, it will not be allowed to access the class library, and malicious code will not be able to use your code to indirectly access protected resources. Altro codice che chiama il codice deve essere autorizzato ad accedere alla raccolta.Other code that calls your code must also have permission to access the library. In caso contrario, sarà limitata anche l'esecuzione del codice.If it does not, your code will be restricted from running as well.

La sicurezza per l'accesso al codice non elimina la possibilità di errori umani nella scrittura del codice.Code access security does not eliminate the possibility of human error in writing code. Tuttavia, se l'applicazione usa le librerie di classi protette per accedere alle risorse protette, il rischio di problemi relativi alla sicurezza del codice applicazione risulta ridotto dall'accurato controllo cui sono sottoposte le librerie di classi.However, if your application uses secure class libraries to access protected resources, the security risk for application code is decreased, because class libraries are closely scrutinized for potential security problems.

Sicurezza dichiarativaDeclarative Security

La sintassi di sicurezza dichiarativa utilizza gli attributi per inserire le informazioni di sicurezza nei metadati del codice.Declarative security syntax uses attributes to place security information into the metadata of your code. Gli attributi possono essere inseriti a livello di assembly, classe o membro, per indicare il tipo di richiesta, la domanda o l'override che si vuole usare.Attributes can be placed at the assembly, class, or member level, to indicate the type of request, demand, or override you want to use. Le richieste vengono usate in applicazioni destinate a Common Language Runtime per informare il sistema di sicurezza runtime sulle autorizzazioni necessarie o non necessarie per l'applicazione.Requests are used in applications that target the common language runtime to inform the runtime security system about the permissions that your application needs or does not want. Le richieste e gli override vengono usati nelle librerie per proteggere le risorse dai chiamanti o per eseguire l'override del comportamento di sicurezza predefinito.Demands and overrides are used in libraries to help protect resources from callers or to override default security behavior.

Nota

In .NET Framework 4 sono state apportate importanti modifiche al modello di sicurezza e alla terminologia di .NET Framework.In the .NET Framework 4, there have been important changes to the .NET Framework security model and terminology. Per ulteriori informazioni su queste modifiche, vedere Modifiche alla sicurezza.For more information about these changes, see Security Changes.

Per usare le chiamate di sicurezza dichiarativa, è necessario inizializzare i dati dello stato dell'oggetto di autorizzazione in modo che rappresenti la forma specifica di autorizzazione necessaria.In order to use declarative security calls, you must initialize the state data of the permission object so that it represents the particular form of permission you need. Ciascuna autorizzazione incorporata dispone di un attributo a cui viene passata un'enumerazione SecurityAction per descrivere il tipo di operazione di protezione che si vuole eseguire.Every built-in permission has an attribute that is passed a SecurityAction enumeration to describe the type of security operation you want to perform. Tuttavia, le autorizzazioni accettano anche i propri parametri esclusivi.However, permissions also accept their own parameters that are exclusive to them.

Nel frammento di codice riportato di seguito viene illustrata la sintassi dichiarativa per richiedere che i chiamanti del codice dispongano di un'autorizzazione personalizzata denominata MyPermission.The following code fragment shows declarative syntax for requesting that your code's callers have a custom permission called MyPermission. Questa autorizzazione è un'autorizzazione personalizzata ipotetica e non esiste in .NET Framework.This permission is a hypothetical custom permission and does not exist in the .NET Framework. In questo esempio viene effettuata la chiamata dichiarativa direttamente prima della definizione di classe, specificando che è necessario applicare l'autorizzazione a livello di classe.In this example, the declarative call is placed directly before the class definition, specifying that this permission be applied to the class level. All'attributo viene passata una struttura SecurityAction.Demand per specificare che i chiamanti devono disporre di questa autorizzazione per poter essere eseguiti.The attribute is passed a SecurityAction.Demand structure to specify that callers must have this permission in order to run.

<MyPermission(SecurityAction.Demand, Unrestricted = True)> Public Class MyClass1

   Public Sub New()
      'The constructor is protected by the security call.
   End Sub

   Public Sub MyMethod()
      'This method is protected by the security call.
   End Sub

   Public Sub YourMethod()
      'This method is protected by the security call.
   End Sub
End Class
[MyPermission(SecurityAction.Demand, Unrestricted = true)]
public class MyClass
{
   public MyClass()
   {
      //The constructor is protected by the security call.
   }

   public void MyMethod()
   {
      //This method is protected by the security call.
   }

   public void YourMethod()
   {
      //This method is protected by the security call.
   }
}

Sicurezza imperativaImperative Security

La sintassi di sicurezza imperativa invia una chiamata di sicurezza mediante la creazione di una nuova istanza dell'oggetto autorizzazione che si vuole richiamare.Imperative security syntax issues a security call by creating a new instance of the permission object you want to invoke. È possibile usare la sintassi imperativa per eseguire domande e override, ma non richieste.You can use imperative syntax to perform demands and overrides, but not requests.

Prima di eseguire la chiamata di sicurezza, è necessario inizializzare i dati dello stato dell'oggetto di autorizzazione in modo che rappresenti la forma specifica di autorizzazione necessaria.Before you make the security call, you must initialize the state data of the permission object so that it represents the particular form of the permission you need. Ad esempio, quando FileIOPermission si crea un oggetto, è possibile utilizzare il costruttore per inizializzare il FileIOPermission oggetto in modo che rappresenti l'accesso illimitato a tutti i file o nessun accesso ai file.For example, when creating a FileIOPermission object, you can use the constructor to initialize the FileIOPermission object so that it represents either unrestricted access to all files or no access to files. In alternativa, è possibile utilizzare un oggetto FileIOPermission diverso, passando parametri che indicano il tipo di accesso che si desidera venga rappresentato dall'oggetto, ovvero lettura, aggiunta o scrittura, e i file che si desidera vengano protetti dall'oggetto.Or, you can use a different FileIOPermission object, passing parameters that indicate the type of access you want the object to represent (that is, read, append, or write) and what files you want the object to protect.

Oltre a usare la sintassi di sicurezza imperativa per richiamare un singolo oggetto di sicurezza, è possibile usarla per inizializzare un gruppo di autorizzazioni in un set di autorizzazioni.In addition to using imperative security syntax to invoke a single security object, you can use it to initialize a group of permissions in a permission set. Ad esempio, questa tecnica è l'unico modo per eseguire in modo affidabile le chiamate di asserzione su più autorizzazioni in un metodo.For example, this technique is the only way to reliably perform assert calls on multiple permissions in one method. Usare le classi PermissionSet e NamedPermissionSet per creare un gruppo di autorizzazioni e quindi chiamare il metodo appropriato per richiamare la chiamata di sicurezza desiderato.Use the PermissionSet and NamedPermissionSet classes to create a group of permissions and then call the appropriate method to invoke the desired security call.

È possibile usare la sintassi imperativa per eseguire domande e override, ma non richieste.You can use imperative syntax to perform demands and overrides, but not requests. Potrebbe usare la sintassi imperativa per richieste e override anziché la sintassi dichiarativa quando le informazioni necessarie per inizializzare lo stato di autorizzazione diventano note solo in fase di esecuzione.You might use imperative syntax for demands and overrides instead of declarative syntax when information that you need in order to initialize the permission state becomes known only at run time. Ad esempio, se si vuole garantire che i chiamanti abbiano l'autorizzazione di lettura di un determinato file, ma non si conosce il nome del file fino al runtime, usare una richiesta imperativa.For example, if you want to ensure that callers have permission to read a certain file, but you do not know the name of that file until run time, use an imperative demand. È anche possibile usare controlli imperativi invece di controlli dichiarativi quando è necessario determinare in fase di esecuzione se contiene una condizione e, in base al risultato del test, eseguire o no una richiesta di sicurezza.You might also choose to use imperative checks instead of declarative checks when you need to determine at run time whether a condition holds and, based on the result of the test, make a security demand (or not).

Nel frammento di codice riportato di seguito viene illustrata la sintassi imperativa per richiedere che i chiamanti del codice abbiano un'autorizzazione personalizzata denominata MyPermission.The following code fragment shows imperative syntax for requesting that your code's callers have a custom permission called MyPermission. Questa autorizzazione è un'autorizzazione personalizzata ipotetica e non esiste in .NET Framework.This permission is a hypothetical custom permission and does not exist in the .NET Framework. Una nuova istanza di MyPermission viene creata in MyMethod e protegge solo questo metodo con la chiamata di sicurezza.A new instance of MyPermission is created in MyMethod, guarding only this method with the security call.

Public Class MyClass1

   Public Sub New()

   End Sub

   Public Sub MyMethod()
      'MyPermission is demanded using imperative syntax.
      Dim Perm As New MyPermission()
      Perm.Demand()
      'This method is protected by the security call.
   End Sub

   Public Sub YourMethod()
      'YourMethod 'This method is not protected by the security call.
   End Sub
End Class
public class MyClass {
   public MyClass(){

   }

   public void MyMethod() {
       //MyPermission is demanded using imperative syntax.
       MyPermission Perm = new MyPermission();
       Perm.Demand();
       //This method is protected by the security call.
   }

   public void YourMethod() {
       //This method is not protected by the security call.
   }
}

Utilizzo di classi wrapper gestiteUsing Managed Wrapper Classes

È necessario che la maggior parte delle applicazione e dei componenti, fatta eccezione per le librerie protette, non chiami direttamente codice non gestito.Most applications and components (except secure libraries) should not directly call unmanaged code. Le ragioni sono molteplici.There are several reasons for this. Se il codice chiama direttamente codice non gestito, in molti casi non ne sarà autorizzata l'esecuzione, poiché per chiamare codice nativo è necessario che il codice disponga di un livello di attendibilità elevato.If code calls unmanaged code directly, it will not be allowed to run in many circumstances because code must be granted a high level of trust to call native code. Se i criteri vengono modificati in modo da consentire l'esecuzione di tale applicazione, potrebbe risultarne seriamente indebolita la protezione del sistema e l'applicazione sarebbe libera di eseguire quasi ogni tipo di operazione.If policy is modified to allow such an application to run, it can significantly weaken the security of the system, leaving the application free to perform almost any operation.

È inoltre probabile che il codice che dispone dell'autorizzazione per l'accesso a codice sia in grado di effettuare qualsiasi operazione chiamando un'API non gestita.Additionally, code that has permission to access unmanaged code can probably perform almost any operation by calling into an unmanaged API. Ad esempio, il codice che dispone dell'autorizzazione per chiamare codice non gestito non è necessario FileIOPermission accedere a un file; può semplicemente chiamare direttamente un'API di file non gestita (Win32), ignorando l'API del file gestito che richiede FileIOPermission.For example, code that has permission to call unmanaged code does not need FileIOPermission to access a file; it can just call an unmanaged (Win32) file API directly, bypassing the managed file API that requires FileIOPermission. Se il codice gestito è autorizzato a chiamare codice non gestito e lo chiama direttamente, il sistema di protezione non sarà in grado di imporre in maniera affidabile restrizioni di protezione, dal momento che non è possibile imporre tali restrizioni su codice non gestito.If managed code has permission to call into unmanaged code and does call directly into unmanaged code, the security system will be unable to reliably enforce security restrictions, since the runtime cannot enforce such restrictions on unmanaged code.

Se si vuole che l'applicazione esegua un'operazione che richiede l'accesso a codice non gestito, sarà necessario usare, se disponibile, una classe gestita attendibile che esegua il wrapping della funzionalità richiesta.If you want your application to perform an operation that requires accessing unmanaged code, it should do so through a trusted managed class that wraps the required functionality (if such a class exists). Non creare autonomamente una classe wrapper se ne esiste già una in una libreria di classi protetta.Do not create a wrapper class yourself if one already exists in a secure class library. La classe wrapper, a cui è necessario concedere un elevato livello di attendibilità perché le sia consentito chiamare codice non gestito, impone ai chiamanti il possesso delle opportune autorizzazioni.The wrapper class, which must be granted a high degree of trust to be allowed to make the call into unmanaged code, is responsible for demanding that its callers have the appropriate permissions. Se si usa una classe wrapper, è necessario che il codice richieda e ottenga esclusivamente le autorizzazioni da essa pretese.If you use the wrapper class, your code only needs to request and be granted the permissions that the wrapper class demands.

Vedere ancheSee also