La protezione dall'accesso di codice è un modello di limitazione delle risorse che consente agli amministratori di determinare se e come un determinato codice possa accedere a risorse specifiche ed eseguire altre operazioni con privilegi. Questo modulo verte sulla configurazione dei criteri di protezione dall'accesso di codice di ASP.NET e in esso viene spiegato come superare i principali ostacoli che si potrebbero incontrare durante lo sviluppo di applicazioni Web con attendibilità parziale.
Vengono spiegati in dettaglio gli elementi pratici della protezione dall'accesso di codice, si vedrà inoltre come sviluppare applicazioni Web con attendibilità media che, pur avvantaggiandosi della protezione dall'accesso di codice, sono in grado di utilizzare componenti che richiedono l'attendibilità totale.
Nel modulo sono inoltre incluse informazioni su come creare criteri di attendibilità personalizzati in ASP.NET, oltre a due preziosi elenchi:
| • | Gli assembly di sistema ai quali è stato applicato APTCA (AllowPartiallyTrustedCallersAttribute). |
| • | Le autorizzazioni dei criteri e i relativi livelli di attendibilità predefiniti di ASP.NET che specificano le principali limitazioni imposte da ciascun livello di attendibilità di ASP.NET. |
Il modulo consente di:
| • | Conoscere il funzionamento dei file dei criteri di ASP.NET e imparare a creare criteri personalizzati. |
| • | Sviluppare applicazioni Web con attendibilità parziale. |
| • | Utilizzare OLE DB, il registro eventi, i servizi Web e il Registro di sistema da applicazioni Web con attendibilità parziale. |
| • | Eseguire codice con privilegi nel sandbox. |
| • | Sapere quando effettuare il sandboxing e quando personalizzare i criteri di attendibilità esistenti di ASP.NET. |
Le informazioni contenute in questo modulo sono valide per i seguenti prodotti e tecnologie:
| • | Microsoft® Windows® 2000 Server e Microsoft Windows Server™ 2003 |
| • | Microsoft .NET Framework 1.1 e ASP.NET 1.1 |
In questo modulo non sono contenute le nozioni fondamentali relative alla protezione dall'accesso di codice. Si presuppone che il lettore già disponga delle conoscenze di base, nonostante i concetti vengano ribaditi, ove opportuno. Per ulteriori informazioni sul funzionamento della protezione dall'accesso di codice, consultare il modulo 8 "Protezione dall'accesso di codice".
Utilizzare questo modulo per informazioni sulle modalità di utilizzo della protezione dall'accesso di codice per bloccare le applicazioni Web sviluppate e rafforzare il server contro potenziali attacchi.
Se si gestiscono ambienti di hosting condivisi o si svolgono attività di provider di servizi Internet con l'esecuzione di varie applicazioni di diverse società nello stesso server Web è possibile utilizzare la protezione dall'accesso di codice per:
| • | Isolare le applicazioni le une dalle altre .
|
| • | Isolare le applicazioni dalle risorse di sistema.
|
Si noti inoltre che Windows Server 2003 e Internet Information Services (IIS) 6.0 offrono un ulteriore isolamento dei processi per le applicazioni Web. L'unione fra isolamento dei processi e protezione dall'accesso di codice costituisce il modello consigliato per l'isolamento delle applicazioni.
Per ulteriori informazioni, consultare il modulo 20 "Host di più applicazioni ASP.NET".
Con la protezione tradizionale, basata sull'identità, ad esempio quella fornita dal sistema operativo, l'accesso alle risorse viene autorizzato in base all'identità dell'utente.
Con Microsoft .NET Framework versione 1.1, gli amministratori possono configurare criteri per le applicazioni e i servizi Web ASP.NET, i quali possono essere costituiti da vari assembly, e concedere autorizzazioni di protezione dall'accesso di codice per consentire alle applicazioni di accedere a tipi di risorse specifici, nonché eseguire determinate operazioni con privilegi.
Ad esempio:
| • | Un amministratore potrebbe decidere che al codice scaricato da Internet non debba essere concessa l'autorizzazione ad accedere a qualsiasi risorsa mentre al codice di un'applicazione Web sviluppata da una determinata società debba essere attribuito un grado di attendibilità maggiore e possa esserle concesso, ad esempio, di accedere al file system, al registro eventi e ai database di Microsoft SQL Server. |
| • | I programmi avviati da un amministratore locale non sono soggetti a limitazioni nel computer locale. Se però l'identità dell'amministratore fosse oggetto di spoofing, un utente malintenzionato potrebbe eseguire codice utilizzando il contesto di protezione dell'amministratore e quindi non essere a sua volta soggetto a limitazioni. |
Sono queste le aree in cui la protezione dall'accesso di codice riveste maggiore importanza, in quanto è in grado di fornire ulteriori limitazioni e protezione basate sul codice in sé, anziché sull'utente che lo esegue.
Nota: le applicazioni e i servizi Web costruiti utilizzando .NET Framework versione 1.0 vengono sempre eseguiti con autorizzazioni all'accesso di codice illimitate. Questa caratteristica non è configurabile.
L'accesso a tutte le risorse dalle applicazioni ASP.NET, e dal codice gestito in generale, è soggetto ai due livelli di protezione indicati di seguito:
| • | Protezione dall'accesso di codice. A questo livello di protezione viene eseguita la verifica che tutto il codice incluso nello stack di chiamate corrente, fino al codice di accesso alle risorse compreso, sia autorizzato ad accedere alla risorsa. L'amministratore utilizza i criteri di protezione dall'accesso di codice per concedere le autorizzazioni agli assembly. Le autorizzazioni determinano con precisione a quali tipi di risorse può accedere l'assembly. Vari tipi di autorizzazioni corrispondono ai diversi tipi di risorse alle quali è possibile accedere. Questi tipi includono il file system, il Registro di sistema, il registro eventi, i servizi directory, Microsoft SQL Server™, le origini dati OLE DB e le risorse di rete.
|
| • | Protezione del sistema operativo/piattaforma. A questo livello di protezione viene eseguita la verifica che il contesto del thread richiedente possa accedere alla risorsa. Se il thread utilizza la rappresentazione, viene utilizzato il token di rappresentazione del thread. In caso contrario viene utilizzato il token del processo che viene confrontato con l'elenco di controllo di accesso (ACL, Access Control List) allegato alla risorsa, per determinare se l'operazione richiesta possa essere eseguita e se sia possibile accedere alla risorsa. |
Entrambi i controlli devono avere esito positivo perché sia possibile accedere correttamente alla risorsa. Tutti i tipi di risorse esposte dalla classi di .NET Framework sono protette con autorizzazioni all'accesso di codice. Nella Figura 9.1 è illustrato un intervallo di tipi di risorse comuni alle quali accedono le applicazioni Web, oltre che l'autorizzazione all'accesso di codice associata, necessaria perché il tentativo di accesso abbia esito positivo.

Figura 9.1
Tipi di risorse comuni a cui accedono le applicazioni Web ASP.NET e tipi di autorizzazioni ad essi associati
Per impostazione predefinita le applicazioni Web vengono eseguite con attendibilità totale. Alle applicazioni con attendibilità totale vengono concesse autorizzazioni all'accesso di codice illimitate, in base ai criteri di protezione dall'accesso di codice. Queste autorizzazioni comprendono sia autorizzazioni di sistema predefinite sia personalizzate. Ciò implica che la protezione dall'accesso di codice non impedirà all'applicazione di accedere ai tipi di risorse protette, illustrate nella Figura 9.1. La riuscita o l'insuccesso del tentativo di accesso alla risorsa è determinato esclusivamente dalla protezione a livello del sistema operativo. Le applicazioni Web in esecuzione con attendibilità totale includono tutte le applicazioni ASP.NET costruite utilizzando .NET Framework versione 1.0 Le applicazioni di .NET Framework versione 1.1 vengono eseguite con attendibilità totale per impostazione predefinita, ma è possibile configurarne il livello di attendibilità utilizzando l'elemento <trust>, descritto più avanti in questo modulo.
Se un'applicazione è configurata con un livello di attendibilità che non sia totale, viene definita applicazione con attendibilità parziale. Le applicazioni con attendibilità parziale dispongono di autorizzazioni limitate, che ne riducono la capacità di accedere a risorse protette.
Importante: Le applicazioni Web costruite utilizzando .NET Framework versione 1.0 vengono sempre eseguite con attendibilità totale perché i tipi inclusi in System.Web richiedono che i chiamanti dispongano dell'attendibilità totale.
Per impostazione predefinita le applicazioni Web vengono eseguite con attendibilità totale e dispongono di autorizzazioni illimitate. Per modificare i livelli di attendibilità della protezione dall'accesso di codice in ASP.NET è necessario impostare un'opzione in Machine.config o Web.config per configurare l'applicazione in modo che le venga concessa l'attendibilità parziale.
L'elemento <trust> di Machine.config controlla se per un'applicazione è o non è attivata la protezione dall'accesso di codice. Aprire Machine.config e cercare "<trust>", si vedrà quanto riportato di seguito.
<system.web>
<!-- level="[Full|High|Medium|Low|Minimal]" -->
<trust level="Full" originUrl=""/>
</system.web>
Con il livello di attendibilità impostato a "Full" la protezione dall'accesso di codice è di fatto disattivata, in quanto le richieste di autorizzazione non ostacolano i tentativi di accesso alle risorse. Questa è la sola opzione disponibile per le applicazioni Web ASP.NET costruite con .NET Framework versione 1.0. Man mano che si scorre l'elenco da "Full" a "Minimal", a ogni livello vengono eliminate sempre più autorizzazioni, il che limita ulteriormente la capacità dell'applicazione di accedere a risorse protette ed eseguire operazioni con privilegi. Ogni livello apporta un maggior grado di isolamento delle applicazioni. Nella Tabella 9.1 sono riportati i livelli di attendibilità predefiniti e sono indicate le principali limitazioni rispetto al livello precedente.
Tabella 9.1 Limitazioni imposte dai livelli di attendibilità di ASP.NET
| Livello di attendibilità di ASP.NET | Limitazioni principali |
Totale | Autorizzazioni illimitate. Le applicazioni possono accedere a qualsiasi risorsa soggetta alla protezione del sistema operativo. Le operazioni con privilegi sono tutte supportate. |
Alto | Impossibilità di chiamare codice non gestito |
Medio | Oltre a quanto specificato in precedenza, l'accesso ai file è limitato alla directory dell'applicazione corrente e non è consentito l'accesso al Registro di sistema. |
Basso | Oltre a quanto specificato in precedenza, l'applicazione non può connettersi a SQL Server e il codice non può accedere a CodeAccessPermission.Assert (autorizzazione alla protezione delle asserzioni) |
Minimo | È disponibile solo l'autorizzazione all'esecuzione. |
Se l'amministratore di un server Web desidera utilizzare la protezione dall'accesso di codice per grantire l'isolamento delle applicazioni e limitare l'accesso alle risorse a livello di sistema, dovrà definire criteri di protezione a livello del computer e impedire che singole applicazioni possano ignorarli.
I provider di servizi applicativi o i responsabili dell'esecuzione di varie applicazioni Web sullo stesso server dovrebbero bloccare il livello di attendibilità di tutte le applicazioni. Per ottenere questo risultato, inserire l'elemento <trust> di Machine.config in un tag <location> e impostare l'attributo allowOverride a false, come illustrato nell'esempio riportato di seguito.
<location allowOverride="false">
<system.web>
<!-- level="[Full|High|Medium|Low|Minimal]" -->
<trust level="Medium" originUrl=""/>
</system.web>
</location>
È altresì possibile utilizzare l'attributo path nell'elemento <location> per applicare a un sito o applicazione Web specifica una configurazione che non può essere ignorata. Per ulteriori informazioni sull'elemento <location> , vedere il modulo 19 "Protezione dell'applicazione ASP.NET e dei servizi Web".
Ogni livello di attendibilità è mappato a un singolo file dei criteri XML e nel file è contenuto il set di autorizzazioni concesso da ogni livello di attendibilità. I file dei criteri sono contenuti nella directory indicata di seguito:
%windir%\Microsoft.NET\Framework\{version}\CONFIG
I livelli di attendibilità vengono mappati ai file dei criteri dagli elementi <trustLevel> di Machine.config, che si trovano immediatamente sopra l'elemento <trust> , come illustrato nell'esempio riportato di seguito.
<location allowOverride="true">
<system.web>
<securityPolicy>
<trustLevel name="Full" policyFile="internal"/>
<trustLevel name="High" policyFile="web_hightrust.config"/>
<trustLevel name="Medium" policyFile="web_mediumtrust.config"/>
<trustLevel name="Low" policyFile="web_lowtrust.config"/>
<trustLevel name="Minimal" policyFile="web_minimaltrust.config"/>
</securityPolicy>
<!-- level="[Full|High|Medium|Low|Minimal]" -->
<trust level="Full" originUrl=""/>
</system.web>
</location>
Nota: per il livello dell'attendibilità totale non esiste un file dei criteri. Si tratta di un caso particolare che indica semplicemente il set illimitato di tutte le autorizzazioni.
I criteri ASP.NET sono interamente configurabili. Oltre ai livelli di criteri predefiniti, gli amministratori possono creare file di autorizzazioni personalizzati e configurarli utilizzando l'elemento <trust>, descritto più avanti in questo modulo. Il file dei criteri associato al livello personalizzato deve inoltre essere definito da un elemento <trustLevel> in Machine.config.
I criteri di protezione dall'accesso di codice sono gerarchici e vengono amministrati a diversi livelli. È possibile creare criteri a livello di organizzazione, computer, utente e dominio applicazione. I criteri di protezione dall'accesso di codice di ASP.NET sono un esempio di criteri a livello di dominio applicazione.
Le impostazioni contenute in un file di configurazione XML distinto definiscono i criteri per ogni livello. I criteri di organizzazione, computer e utente possono essere configurati utilizzando lo strumento di configurazione di Microsoft .NET Framework, ma i file dei criteri ASP.NET devono essere modificati manualmente avvalendosi di un editor di testo o XML.
I singoli file di criteri per il livello di attendibilità di ASP.NET stabiliscono quali autorizzazioni possono essere concesse alle applicazioni configurate con un determinato livello di attendibilità. Le autorizzazioni effettive che vengono concesse a un'applicazione ASP.NET sono determinate mediante intersezione delle autorizzazioni concesse da tutti i livelli di criteri, compresi quelli di organizzazione, computer, utente e ASP.NET (dominio applicazione).
Dato che i criteri vengono valutati partendo dal livello organizzazione e procedendo verso il basso, fino al livello dell'applicazione ASP.NET, le autorizzazioni possono solo essere rimosse. Non è possibile aggiungere un'autorizzazione al livello ASP.NET senza che questa sia stata precedentemente concessa a un livello superiore. Questo approccio garantisce che l'amministratore dell'organizzazione abbia sempre la situazione sotto controllo e che eventuale codice nocivo in esecuzione in un dominio applicazione non possa richiedere e ottenere autorizzazioni maggiori rispetto a quelle configurate dall'amministratore.
Per ulteriori informazioni sulla valutazione dei criteri, consultare il modulo 8 "Protezione dall'accesso di codice".
Per vedere quali autorizzazioni sono definite da un determinato livello di attendibilità, aprire il relativo file nel Blocco note oppure, preferibilmente, in un editor XML e individuare il set di autorizzazioni denominato "ASP.NET". Nel set sono elencate le autorizzazioni configurate per l'applicazione al livello di attendibilità corrente.
Nota: si noteranno inoltre i set di autorizzazioni "FullTrust" e "Nothing". In questi set non sono contenuti elementi di autorizzazione perché "FullTrust" le implica tutte mentre "Nothing" non ne contiene nessuna.
Di seguito sono riportati gli elementi principali di un file dei criteri ASP.NET:
<configuration>
<mscorlib>
<security>
<policy>
<PolicyLevel version="1">
<SecurityClasses>
... list of security classes, permission types,
and code group types ...
</SecurityClasses>
<NamedPermissionSets>
<PermissionSet Name="FullTrust" ... />
<PermissionSet Name="Nothing" .../>
<PermissionSet Name="ASP.NET" ...
... This is the interesting part ...
... List of individual permissions...
<IPermission
class="AspNetHostingPermission"
version="1"
Level="High" />
<IPermission
class="DnsPermission"
version="1"
Unrestricted="true" />
...Continued list of permissions...
</PermissionSet>
</PolicyLevel version="1">
</policy>
</security>
</mscorlib>
</configuration>
Si noti che ogni autorizzazione è definita da un elemento <IPermission> che stabilisce il nome del tipo di autorizzazione, la versione e se l'autorizzazione sia o non sia illimitata.
Molte autorizzazioni includono lo stato, che viene utilizzato per ottimizzare i diritti di accesso che esse specificano. Lo stato determina con esattezza quali operazioni l'autorizzazione consente all'applicazione di eseguire. L'autorizzazione FileIOPermission specifica ad esempio una directory e un tipo di accesso (lettura, scrittura e così via). Per la richiesta di autorizzazione riportata di seguito è necessario che al codice chiamante sia concessa l'autorizzazione alla lettura per accedere alla directory C:\Directory.
(new FileIOPermission(FileIOPermissionAccess.Read, @"C:\SomeDir")).Demand();
Se illimitata, l'autorizzazione FileIOPermission consente qualsiasi tipo di accesso a qualsiasi area del file system, anche se naturalmente la protezione del sistema operativo continua a essere valida. Per la richiesta di autorizzazione riportata di seguito è necessario che al codice chiamante sia concessa l'autorizzazione FileIOPermission illimitata:
(new FileIOPermission(PermissionState.Unrestricted)).Demand();
I file dei criteri di ASP.NET contengono un set di autorizzazioni denominato "ASP.NET" che definisce le autorizzazioni concesse alle applicazioni associate dai criteri del dominio applicazione.
I criteri ASP.NET presentano inoltre un'autorizzazione AspNetHostingPermission personalizzata, che dispone dell'attributo Level associato, corrispondente a uno dei livelli predefiniti. Tutti i tipi pubblici contenuti in System.Web e System.Web.Mobile sono protetti con richieste del livello minimo di questa autorizzazione. Questa strategia di riduzione del rischio è progettata per avere la certezza che il codice delle applicazioni Web non possa essere utilizzato in altri ambienti con attendibilità parziale in assenza di criteri specifici configurati da una amministratore.
Se si modifica uno dei file dei criteri di .NET, si noterà che alcuni elementi di autorizzazione contengono parametri di sostituzione ($AppDirUrl$, $CodeGen$ e $Gac$). Questi parametri consentono di configurare le autorizzazioni per gli assembly che fanno parte dell'applicazione Web, ma vengono caricati da percorsi diversi. Ogni parametro di sostituzione viene sostituito con un valore effettivo al momento della valutazione dei criteri di protezione, che si verifica quando l'assembly dell'applicazione Web viene caricato per la prima volta. L'applicazione Web può essere costituita dai tre tipi di assembly riportati di seguito:
| • | Assembly privati completati al momento della build e distribuiti nella directory bin dell'applicazione Importante: Questo tipo di assembly non può disporre di un nome sicuro. Gli assembly con nome sicuro utilizzati dalle applicazioni Web di ASP.NET devono essere installati nella cache globale. Questa limitazione è necessaria a causa del funzionamento interno del processo di lavoro di un dominio con più applicazioni. |
| • | Assembly compilati dinamicamente, generati in risposta a una richiesta di pagina |
| • | Assembly condivisi, caricati dalla cache globale del computer |
A tutti questi tipi di assembly è associato un parametro di sostituzione, riepilogato nella Tabella 9.2.
Tabella 9.2 Parametri di sostituzione dei criteri di protezione dall'accesso di codice di ASP.NET
| Parametro | Rappresenta |
$AppDirUrl$ | La directory virtuale principale dell'applicazione. Consente di applicare autorizzazioni al codice presente nella directory bin dell'applicazione. Se una directory virtuale è, ad esempio, mappata a C:\ApplicazioneWeb, $AppDirUrl$ equivarrà a C:\ApplicazioneWeb. |
$CodeGen$ | La directory contenente assembly generati dinamicamente, ad esempio il risultato della compilazione di una pagina aspx. Può essere configurato applicazione per applicazione e ha come impostazione predefinita |
$Gac$ | Tutti gli assembly installati nella cache globale (%windir%\assembly). Consente di concedere autorizzazioni agli assembly con nome sicuro caricati dall'applicazione Web dalla cache globale. |
Le applicazioni Web con attendibilità parziale sono applicazioni che dispongono di un set di autorizzazioni all'accesso di codice limitate, determinate dai criteri di protezione dall'accesso di codice. Ne consegue che le applicazioni con attendibilità parziale hanno una capacità limitata di accedere alle risorse protette ed eseguire altre operazioni con privilegi. Alcune autorizzazioni sono negate alle applicazioni con attendibilità parziale, pertanto queste applicazioni non possono accedere direttamente alle risorse che le richiedono. Altre autorizzazioni sono loro concesse in maniera limitata, pertanto le corrispondenti risorse potrebbero risultare accessibili, sebbene con dei limiti. Un'autorizzazione FileIOPermission limitata potrebbe ad esempio specificare che l'applicazione può accedere al file system, ma solo nelle sottodirectory della directory virtuale principale dell'applicazione.
Configurando un'applicazione o servizio Web con l'attendibilità parziale è possibile limitarne la capacità di accedere a risorse critiche del sistema o a risorse appartenenti ad altre applicazioni Web. Concedendo solo le autorizzazioni necessarie per l'applicazione e nulla più, è possibile costruire applicazioni Web con meno privilegi e limitare i potenziali danni che potrebbero essere causati nel caso l'applicazione Web fosse compromessa da un attacco mediante inserimento di codice (code injection).
Se si utilizza un'applicazione Web e la si riconfigura in modo che venga eseguita a un livello con attendibilità parziale, è probabile che si verifichino i problemi descritti di seguito, a meno che non vengano imposti limiti molto restrittivi relativamente alle risorse alle quali l'applicazione può accedere:
| • | L'applicazione non è in grado di chiamare assembly con nome sicuro ai quali non sia stato aggiunto l'attributo AllowPartiallyTrustedCallersAttribute (APTCA). Senza l'attributo APTCA, gli assembly con nome sicuro richiedono l'attendibilità totale, si verifica quindi un errore quando la richiesta raggiunge l'applicazione Web con attendibilità parziale. Molti assembly di sistema supportano esclusivamente chiamanti con attendibilità totale. Nell'elenco seguente sono riportati gli assembly di .NET Framework che supportano chiamanti con attendibilità parziale e che possono essere chiamati direttamente da applicazioni Web con attendibilità parziale senza la necessità di eseguire assembly wrapper nel sandbox. Nota: il sandboxing sarà trattato con maggiore dettaglio più avanti in questo modulo. Agli assembly di sistema riportati di seguito è stato applicato l'attributo APTCA, vale a dire che possono essere chiamati da applicazioni Web o da codice con attendibilità parziale:
Se l'applicazione con attendibilità parziale non viene eseguita correttamente a causa del fatto che chiama un assembly con nome sicuro ma non dispone dell'attributo APTCA, viene generata un'eccezione generica SecurityException . In questo caso, l'eccezione non contiene informazioni aggiuntive che indichino che la chiamata non ha avuto esito positivo a causa di un errore nella richiesta dell'attendibilità totale. | ||||||||||||||||||||||
| • | Le richieste di autorizzazione possono avviarsi ma non essere completate correttamente. Il livello di attendibilità configurato potrebbe non concedere l'autorizzazione necessaria perché l'applicazione possa accedere a un tipo specifico di risorse. Di seguito sono descritte alcune situazioni comuni in cui ciò può rivelarsi un problema:
|
Se si ha in progetto di trasformare un'applicazione esistente in un'applicazione con attendibilità parziale, un ottimo modo di procedere consiste nel ridurre le autorizzazioni in maniera incrementale, in modo da vedere in quali parti dell'applicazione si verificano problemi. Iniziare, ad esempio, impostando l'attributo level relativo all'attendibilità ad Alto, Medio e così via. In ultima analisi, il livello di attendibilità da adottare dipende dal grado di limitazione che si desidera imporre all'applicazione. Utilizzare quanto riportato di seguito come guida:
| • | Le applicazioni configurate con un livello di attendibilità alto, medio, basso o minimo non possono chiamare codice non gestito o componenti per servizi, scrivere nel registro eventi, accedere alle code di Accodamento messaggi o alle origini dati OLE DB. |
| • | Le applicazioni configurate con attendibilità alta possono accedere al file system senza limitazioni. |
| • | Le applicazioni configurate con attendibilità media possono accedere al file system ma con limitazioni. I soli file ai quali possono accedere sono quelli che fanno parte della propria gerarchia di directory. |
| • | Le applicazioni configurate con attendibilità bassa o minima non possono accedere ai database SQL Server. |
| • | Le applicazioni con attendibilità minima non possono accedere ad alcuna risorsa. |
Nella Tabella 9.3 sono riportate le autorizzazioni concesse da ogni livello di attendibilità di ASP.NET. Il livello di attendibilità totale è stato omesso in quanto in questo caso sono concesse tutte le autorizzazioni senza alcuna limitazione.
Tabella 9.3 Livelli di attendibilità e autorizzazioni dei criteri di ASP.NET
| Autorizzazione e stato | Alto | Medio | Basso | Minimo |
AspNetHosting | Alto | Medio | Basso | Minimo |
DnsPermission |
|
|
|
|
EnvironmentPermission |
| TEMP; TMP; |
|
|
EventLogPermission |
|
|
|
|
FileIOPermission |
|
|
|
|
IsolatedStorageFilePermission |
|
|
|
|
OleDbClientPermission |
|
|
|
|
PrintingPermission |
|
|
|
|
ReflectionPermission |
|
|
|
|
RegistryPermission |
|
|
|
|
SecurityPermission |
|
|
|
|
SocketPermission |
|
|
|
|
SqlClientPermission |
|
|
|
|
WebPermission |
| $OriginHost$ |
|
|
Se si sviluppa un'applicazione con attendibilità parziale o si abilita un'applicazione esistente all'esecuzione al livello di attendibilità parziale e si verifica un problema perché l'applicazione tenta di accedere a risorse per le quali non sono state concesse le necessarie autorizzazioni, è possibile adottare due tipi di approccio di base:
| • | Personalizzare i criteri |
| • | Eseguire il codice con privilegi nel sandbox |
L'approccio corretto dipende dalla natura del problema. Se il problema è correlato al fatto che si sta tentando di chiamare un assembly di sistema che non contiene l'attributo AllowPartiallyTrustedCallersAttribute, la questione di fondo si traduce in come concedere l'attendibilità totale a una parte di codice. In questa situazione è possibile ricorrere al sandboxing e concedere l'attendibilità totale all'assembly wrapper eseguito nel sandbox.
Nota: la personalizzazione dei criteri è la soluzione più semplice in quanto non richiede interventi a livello di sviluppo.
Se l'applicazione Web contiene codice che richiede maggiori autorizzazioni rispetto a quelle concesse da un determinato livello di attendibilità di ASP.NET, la soluzione più semplice consiste nel personalizzare un file di criteri in modo da concedere all'applicazione Web le ulteriori autorizzazioni di protezione dall'accesso di codice. È possibile sia modificare un file di criteri esistente sia crearne uno nuovo da uno esistente allo scopo di concedere ulteriori autorizzazioni.
Nota: se si modifica uno dei file di criteri predefiniti, ad esempio il file Web_mediumtrust.config relativo all'attendibilità media, la modifica avrà effetto su tutte le applicazioni configurate per l'esecuzione con attendibilità media.
| • | Per personalizzare i criteri per un'applicazione specifica
|
Un altro tipo di approccio che non prevede la modifica dei criteri di protezione dall'accesso di codice di ASP.NET consiste nel racchiudere il codice di accesso alle risorse nel proprio assembly wrapper e configurare i criteri di protezione dall'accesso di codice a livello del computer in modo che concedano l'autorizzazione corretta all'assembly specifico. Sarà quindi possibile eseguire nel sandbox il codice con i privilegi più alti utilizzando il metodo CodeAccessPermission.Assert in modo da non dover modificare le autorizzazioni globali dell'applicazione Web. Il metodo Assert impedisce che la richiesta di protezione inviata dal codice di accesso alle risorse si propaghi a ritroso nello stack di chiamate oltre i limiti dell'assembly wrapper.
È possibile applicare lo schema seguente a codice con privilegi che necessita di accedere a una risorsa limitata o di eseguire un'altra operazione con privilegi per cui l'applicazione Web padre non dispone di autorizzazioni sufficienti:
1. | Inserire il codice di accesso alle risorse in un assembly wrapper.
|
2. | Effettuare l'asserzione dell'autorizzazione in questione prima di accedere alla risorsa.
Effettuare l'asserzione delle autorizzazioni è alquanto pericoloso poiché significa che il codice che chiama il proprio codice può accedere alla risorsa incapsulata dall'assembly senza richiedere la relativa autorizzazione di accesso. L'istruzione Assert indica che il codice può garantire la legittimità dei suoi chiamanti. Per effettuare questa operazione, il codice deve chiedere un'autorizzazione alternativa, in modo da poter autorizzare il codice chiamante prima di chiamare Assert. In tal modo si consente di accedere alla risorsa esposta dall'assembly al solo codice cui è stata concessa l'autorizzazione alternativa. .NET Framework potrebbe non concedere alla richiesta un'autorizzazione adatta. In tal caso è possibile creare e richiedere un'autorizzazione personalizzata. Per ulteriori informazioni sulle modalità di creazione di un'autorizzazione personalizzata, vedere "Procedura: creare un'autorizzazione per la crittografia personalizzata" nella sezione "Procedure" di questa guida. |
3. | Aggiungere l'attributo APTCA all'assembly wrapper.
|
4. | Installare l'assembly wrapper nella cache globale <CodeGroup
class="UnionCodeGroup"
version="1"
PermissionSetName="FullTrust>
<IMembershipCondition
class="UrlMembershipCondition"
Url="$Gac$/*"
version="1"
/>
</CodeGroup>
Nota: i criteri predefiniti a livello del computer locale e dell'organizzazione concedono inoltre l'attendibilità totale a tutto il codice che si trova nella zona Risorse del computer, che comprende il codice installato nella cache globale. Questo è importante perché viene eseguita un'operazione di intersezione delle autorizzazioni concesse attraverso i livelli di criteri. |
5. | Configurare il livello di attendibilità dell'applicazione Web (ad esempio a "Medio"). |
Nella Figura 9.2 è illustrato l'approccio che prevede il sandboxing.

Figura 9.2
Sandboxing di codice con privilegi nel relativo assembly con asserzione dell'autorizzazione pertinente
È buona prassi utilizzare assembly distinti per incapsulare l'accesso alle risorse ed evitare di inserire il codice di accesso alle risorse in file aspx o file di codice sottostante. Creare ad esempio un assembly per l'accesso ai dati distinto per incapsulare l'accesso al database. Risulterà in tal modo più semplice effettuare la migrazione delle applicazioni in ambienti con attendibilità parziale.
Il tipo di approccio corretto dipende dal problema che si sta tentando di risolvere e da se esista o non esista la possibilità di modificare i criteri di protezione nel server Web.
Questo tipo di approccio è il più semplice dei due e non richiede attività di sviluppo. Potrebbe tuttavia non essere possibile modificare i criteri nel server Web e, in alcuni casi, il codice che chiama la libreria di classi di .NET Framework potrebbe richiedere l'attendibilità completa. In queste situazioni è opportuno ricorrere al sandboxing. Le risorse riportate di seguito, ad esempio, richiedono l'attendibilità totale e, per accedere alle risorse, è necessario eseguire nel sandbox il relativo codice di accesso:
| • | Registro eventi (attraverso la classe EventLog) |
| • | Origini dati OLE DB (attraverso il provider di dati OLE DB di ADO.NET) |
| • | Origini dati ODBC (attraverso il provider di dati ODBC .NET di ADO.NET) |
| • | Database Oracle (attraverso il provider di dati Oracle .NET di ADO.NET) |
Nota: l'elenco non è completo ma comprende tipi di risorse utilizzati di frequente che attualmente richiedono l'attendibilità totale.
Se si esegue nel sandbox il codice delle applicazioni con privilegi in un assembly distinto, è possibile concedere ulteriori autorizzazioni all'assembly. È in alternativa possibile concedere all'assembly l'attendibilità totale senza che l'intera applicazione venga eseguita con autorizzazioni maggiori.
Si prenda in considerazione, ad esempio, del codice che utilizza il provider di dati OLE DB di ADO.NET e che interagisce con la classe System.Data.OleDb.OleDbCommand. Per tale codice è necessaria l'attendibilità totale. Nonostante l'assembly System.Data.dll disponga dell'attributo AllowPartiallyTrustedCallersAttribute, la classe System.Data.OleDb.OleDbCommand , ma non è la sola, non supporta chiamanti con attendibilità parziale perché è protetta con una richiesta in fase di linking di attendibilità totale. Per vedere quanto descritto, eseguire il comando riportato di seguito utilizzando l'utilità permview dalla directory %windir%\Microsoft.NET\Framework\{versione}:
permview /DECL /OUTPUT System.Data.Perms.txt System.Data.dll
L'output in System.Data.Perms.txt include quanto segue:
class System.Data.OleDb.OleDbCommand LinktimeDemand permission set:
<PermissionSet class="System.Security.PermissionSet"
version="1" Unrestricted="true"/>
Ciò illustra che viene utilizzato un set di autorizzazioni illimitato (attendibilità totale) in una richiesta in fase di linking che protegge la classe System.Data.OleDb.OleDbCommand. In situazioni del genere non è sufficiente configurare i criteri per concedere autorizzazioni illimitate specifiche, ad esempio OleDbPermission, al codice con attendibilità parziale. È necessario invece eseguire nel sandbox il codice di accesso alle risorse e concedergli l'attendibilità totale. Il modo più rapido per svolgere questa operazione consiste nell'installarlo nella cache globale. Utilizzare Permview.exe per trovare informazioni relative ai requisiti di autorizzazione delle altre classi, nonostante vengano visualizzati solo gli attributi di protezione dichiarativi. Se una classe richiede l'attendibilità totale in maniera imperativa, non sarà possibile vederlo in Permview.exe. In questo caso, verificare i requisiti di protezione della classe chiamandola da codice con attendibilità parziale e diagnosticare le eventuali eccezioni di protezione.
Nota: se un assembly è contrassegnato con APTCA, ciò non significa necessariamente che tutte le classi in esso contenute supportino chiamanti con attendibilità parziale. Alcune classi possono contenere richieste esplicite di attendibilità totale.
Se si ospitano applicazioni Web, è possibile scegliere di implementare criteri di protezione con attendibilità media per limitare le operazioni con privilegi. Questa sezione verte sull'esecuzione di applicazioni con attendibilità media e mostra come risolvere i problemi che potrebbero insorgere.
L'esecuzione con attendibilità media comporta i due principali vantaggi descritti di seguito:
| • | Superficie di attacco ridotta |
| • | Isolamento delle applicazioni |
Dato che l'attendibilità media non concede all'applicazione un accesso illimitato a tutte le autorizzazioni, la superficie d'attacco viene ridotta concedendo all'applicazione un set di autorizzazioni secondario rispetto a quello totale. Molte delle autorizzazioni concesse dai criteri dell'attendibilità media sono limitate. Se un pirata informatico riuscisse in qualche modo ad assumere il controllo dell'applicazione, le operazioni che potrebbe svolgere sarebbero comunque limitate.
L'isolamento delle applicazioni con la protezione dall'accesso di codice limita l'accesso alle risorse di sistema e alle risorse di proprietà di altre applicazioni. Nonostante, ad esempio, all'identità del processo possa essere consentito di leggere e scrivere file al di fuori della directory dell'applicazione Web, nel caso di applicazioni con attendibilità media l'autorizzazione FileIOPermission è limitata. Questa autorizzazione consente all'applicazione di leggere o scrivere esclusivamente nella propria gerarchia di directory.
Se l'applicazione viene eseguita con attendibilità media, si trova a fronteggiare diverse limitazioni, le più significative delle quali sono riportate di seguito:
| • | Impossibilità di accedere direttamente al registro eventi. |
| • | Accesso limitato al file system con la possibilità di accedere esclusivamente ai file che fanno parte della gerarchia della propria directory virtuale. |
| • | Impossibilità di accedere direttamente alle origini dati OLE DB, nonostante le applicazioni con attendibilità media dispongano dell'autorizzazione SqlClientPermission, che consente di accedere a SQL Server. |
| • | Accesso limitato ai servizi Web. |
| • | Impossibilità di accedere direttamente al Registro di sistema di Windows. |
In questa sezione viene illustrato come accedere ai tipi di risorse indicati di seguito da un'applicazione o servizio Web con attendibilità media:
| • | OLE DB |
| • | Registro eventi |
| • | Servizi Web |
| • | Registro di sistema |
Alle applicazioni Web con attendibilità media non viene concessa l'autorizzazione OleDbPermission. Il provider di dati OLE DB di .NET richiede inoltre chiamanti con attendibilità totale. Se si utilizza un'applicazione che ha la necessità di accedere a origini dati OLE DB mentre è in esecuzione con attendibilità media, utilizzare il sandboxing. Inserire il codice di accesso ai dati in un assembly distinto, attribuirgli un nome sicuro e installarlo nella cache globale, conferendogli così l'attendibilità totale.
Nota: la modifica dei criteri non funziona a meno che non si imposti il livello di attendibilità come totale dato che il provider gestito OLE DB richiede l'attendibilità totale.
Nella Figura 9.3 è illustrata la disposizione.

Figura 9.3
Sandboxing per l'accesso a risorse OLE DB
Con questo tipo di approccio si crea un assembly wrapper per incapsulare l'accesso alle origini dati OLE DB. A questo assembly vengono concesse le autorizzazioni dell'attendibilità totale, necessarie per utilizzare il provider gestito OLE DB di ADO.NET.
| • | Per costruire un assembly wrapper da eseguire nel sandbox per chiamare origini dati OLE DB
|
La classe EventLogPermission è progettata in modo da incapsulare i diritti del codice di accedere al registro eventi. Perché il codice possa accedere al registro eventi è tuttavia attualmente necessario che gli sia concessa l'attendibilità totale. Ciò significa che un'applicazione Web con attendibilità media non può accedere direttamente al registro eventi. Perché ciò avvenga è necessario eseguire nel sandbox il codice di registrazione eventi.
Accertarsi in primo luogo che l'account del processo utilizzato per l'esecuzione dell'applicazione Web (o l'identità del thread, se l'applicazione utilizza la rappresentazione) sia in grado di creare origini eventi. Per questo il processo o l'identità del thread deve essere in grado di creare chiavi di registro secondarie rispetto alla chiave riportata di seguito:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog
Come minimo l'identità di un processo ASP.NET che utilizza la rappresentazione deve disporre delle seguenti autorizzazioni per questa chiave del Registro di sistema:
| • | Ricerca valore chiave |
| • | Imposta valore chiave |
| • | Crea sottochiave |
| • | Enumera sottochiavi |
| • | Notifica |
| • | Lettura |
Queste impostazioni devono essere applicate alla chiave indicata in precedenza e relative sottochiavi. È in alternativa possibile creare origini eventi al momento dell'installazione, quando sono disponibili i privilegi amministrativi. Per ulteriori informazioni su questo tipo di approccio, vedere la sezione "Controllo e registrazione" nel modulo 10 "Creazione di pagine e controlli ASP.NET protetti".
Per eseguire nel sandbox il codice di registrazione eventi, si crea un assembly wrapper per incapsulare l'accesso al registro eventi. L'assembly wrapper viene quindi installato nella cache globale in modo che i criteri di autorizzazione all'accesso di codice gli concedano l'attendibilità totale.
| • | Per costruire un assembly wrapper con sandboxing per scrivere nel registro eventi
|
Per impostazione predefinita, i criteri dell'attendibilità media concedono alle applicazioni Web ASP.NET un'autorizzazione WebPermission limitata. Per poter chiamare servizi Web dall'applicazione Web, è necessario configurare l'attributo originUrl nell'elemento <trust> dell'applicazione.
| • | Per chiamare un singolo servizio Web da un'applicazione Web con attendibilità media
|
Il valore di originUrl viene utilizzato nel costruttore per una classe di espressioni regolari System.Text.RegEx in modo che possa individuare gli URL corrispondenti accessibili dal servizio Web. La classe RegEx viene utilizzata unitamente a una classe WebPermission. Con ".*" vengono individuati gli URL corrispondenti che iniziano con "http://nomeserver/".
L'attributo originUrl viene utilizzato quando vengono valutati i criteri ASP.NET. Fornisce un valore per il parametro di sostituzione $OriginHost$. Di seguito è riportata la definizione di WebPermission tratta da Web_mediumtrust.config:
<IPermission
class="WebPermission"
version="1">
<ConnectAccess>
<URI uri="$OriginHost$"/>
</ConnectAccess>
</Ipermission>
Se non si specificano i server Web ai quali accede l'applicazione, non sarà possibile completare correttamente alcuna richiesta di un servizio Web e verrà generata un'eccezione SecurityException. Per chiamare un servizio Web nel server Web locale utilizzare la configurazione riportata di seguito:
<trust level="Medium" originUrl="http://localhost/.*" />
Se l'applicazione deve poter accedere a vari servizi Web in server diversi, è possibile personalizzare i criteri di ASP.NET in quanto è possibile specificare un solo originUrl nell'elemento <trust> di Web.config o Machine.config.
| • | Per chiamare vari servizi Web da un'applicazione Web con attendibilità media
|
Potrebbe essere necessario chiamare un servizio Web che utilizza l'autenticazione di Windows e specificare credenziali di autorizzazione attraverso la cache delle credenziali proxy. Ad esempio:
proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
In questo caso, l'applicazione ASP.NET necessita dell'autorizzazione EnvironmentPermission con accesso in lettura alla variabile di ambiente USERNAME. I criteri predefiniti dell'attendibilità media concedono questa autorizzazione alle applicazioni Web.
Nel caso del lato server di ASP.NET, le credenziali vengono ottenute dal thread dell'applicazione ASP.NET o dal token a livello di processo. Se viene utilizzato DefaultCredentials da un'applicazione desktop, viene utilizzato il token dell'utente interattivo corrente. La richiesta di EnvironmentPermission costituisce una strategia di riduzione del rischio volta ad assicurare che il codice non possa utilizzare a piacimento le credenziali dell'utente locale ed esporle alla rete.
Per impostazione predefinita, alle applicazioni Web con attendibilità media non viene concessa l'autorizzazione RegistryPermission. Per configurare l'applicazione in modo che acceda al Registro di sistema è necessario modificare i criteri di ASP.NET in modo da concederle questa autorizzazione oppure sviluppare un assembly wrapper con sandboxing che disponga dell'autorizzazione necessaria.
Il tipo di approccio che prevede il sandboxing è identico a quello descritto in precedenza per le origini dati OLE DB e il registro eventi.
Il modo più semplice per personalizzare i criteri consiste nel creare un file di criteri personalizzato basato sul file dei criteri dell'attendibilità media e configurare l'applicazione in modo da utilizzare i criteri personalizzati. I criteri personalizzati concedono all'applicazione l'autorizzazione RegistryPermission.
| • | Per creare criteri personalizzati per consentire l'accesso al Registro di sistema
|
La protezione dall'accesso di codice è un modello di protezione per limitare le risorse, utilizzabile per isolare le applicazioni. È possibile configurare le applicazioni in modo che vengano eseguite con vari livelli di attendibilità parziale. Il livello di attendibilità determina le autorizzazioni concesse a un'applicazione o servizio Web ASP.NET, il tipo di risorse accessibili e gli altri tipi di operazioni con privilegi che possono essere eseguite. Si noti che l'accesso alle risorse è in ultima analisi soggetto alla protezione del sistema operativo.
Il modello di isolamento consigliato utilizza i pool di applicazioni di IIS 6.0 in Windows Server 2003 e fornisce un isolamento a livello dei processi oltre alla protezione dall'accesso di codice. In Windows 2000 è possibile ottenere l'isolamento soltanto utilizzando la protezione dall'accesso di codice e separando le identità dei thread.
Per modificare un'applicazione in modo che venga eseguita con attendibilità parziale è di solito necessario svolgere diverse attività di programmazione. Potrebbe essere necessario ricorrere a ulteriori attività di sviluppo se l'applicazione accede a risorse non consentite dal livello di attendibilità parziale o se chiama assembly dotati di nome sicuro che non contengono l'attributo APTCA. In questi casi è possibile eseguire nel sandbox l'accesso alle risorse in assembly wrapper distinti. In alcuni scenari potrebbe essere possibile creare e utilizzare file di criteri personalizzati, sebbene questo dipenda dai criteri di protezione del server Web.
È buona prassi di programmazione inserire il codice di accesso alle risorse in assembly distinti, evitando di collocarlo in file aspx o file di codice sottostante. L'utilizzo di assembly distinti consente di applicare i criteri di protezione dall'accesso di codice all'assembly indipendentemente dall'applicazione Web, oltre che di sviluppare codice attendibile da eseguire nel sandbox per effettuare l'accesso alle risorse.
Per ulteriori informazioni, vedere le risorse seguenti:
| • | "Security in .NET: The Security Infrastructure of the CLR Provides Evidence, Policy, Permissions, and Enforcement Services" in MSDN Magazine all'indirizzo http://msdn.microsoft.com/msdnmag/issues/02/09/SecurityinNET/default.aspx (in inglese). |
| • | "Security in .NET: Enforce Code Access Rights with the Common Language Runtime" in MSDN Magazine all'indirizzo http://msdn.microsoft.com/msdnmag/issues/01/02/CAS/default.aspx (in inglese). |
| • | .NET Framework Security di LaMacchia, Lange, Lyons, Martin, and Price, Addison Wesley Professional, 2002 (in inglese). |
| • | "Procedura: creare un'autorizzazione per la crittografia personalizzata" nella sezione "Procedure" di questa guida. |