Utilizzo della protezione dall'accesso di codice con ASP.NET

In questa pagina
Argomenti del moduloArgomenti del modulo
ObiettiviObiettivi
Ambito di applicazioneAmbito di applicazione
Utilizzo del moduloUtilizzo del modulo
Cenni preliminariCenni preliminari
Accesso alle risorseAccesso alle risorse
Attendibilità totale e parzialeAttendibilità totale e parziale
Configurazione della protezione dall'accesso di codice in ASP.NETConfigurazione della protezione dall'accesso di codice in ASP.NET
File dei criteri ASP.NETFile dei criteri ASP.NET
Criteri ASP.NETCriteri ASP.NET
Sviluppo di applicazioni Web con attendibilità parziale.Sviluppo di applicazioni Web con attendibilità parziale.
Livelli di attendibilitàLivelli di attendibilità
Tipi di approccio alle applicazioni Web con attendibilità parzialeTipi di approccio alle applicazioni Web con attendibilità parziale
Personalizzazione dei criteriPersonalizzazione dei criteri
Eseguire il codice con privilegi nel sandboxEseguire il codice con privilegi nel sandbox
Scelta del tipo di approccioScelta del tipo di approccio
Attendibilità mediaAttendibilità media
Limitazioni dell'attendibilità mediaLimitazioni dell'attendibilità media
RiepilogoRiepilogo
Risorse aggiuntiveRisorse aggiuntive

Argomenti del modulo

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.

Inizio paginaInizio pagina

Obiettivi

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.

Inizio paginaInizio pagina

Ambito di applicazione

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

Inizio paginaInizio pagina

Utilizzo del modulo

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 .
La protezione dall'accesso di codice può essere utilizzata ad esempio per avere la certezza che un'applicazione Web non possa scrivere nelle directory di un'altra applicazione Web.

Isolare le applicazioni dalle risorse di sistema.
La protezione dall'accesso di codice può, ad esempio, limitare l'accesso a file system, Registro di sistema, registri eventi e risorse di rete, oltre che ad altre 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".

Inizio paginaInizio pagina

Cenni preliminari

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.

Inizio paginaInizio pagina

Accesso alle risorse

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.
Per un elenco completo delle autorizzazioni all'accesso di codice, consultare il modulo 8 "Protezione dall'accesso di codice".

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.

Tipi di risorse comuni a cui accedono le applicazioni Web ASP.NET e tipi di autorizzazioni ad essi associati

Figura 9.1
Tipi di risorse comuni a cui accedono le applicazioni Web ASP.NET e tipi di autorizzazioni ad essi associati

Inizio paginaInizio pagina

Attendibilità totale e parziale

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.

Inizio paginaInizio pagina

Configurazione della protezione dall'accesso di codice in ASP.NET

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.

Configurazione dei livelli di attendibilità

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.NETLimitazioni 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
Impossibilità di chiamare componenti per servizi
Impossibilità di scrivere nel registro eventi
Impossibilità di accedere alle code di Microsoft Accodamento messaggi
Impossibilità di accedere alle origini dati OLE DB

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.

Blocco del livello di attendibilità

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".

Inizio paginaInizio pagina

File dei criteri ASP.NET

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.

Inizio paginaInizio pagina

Criteri ASP.NET

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".

Contenuto di un file dei criteri ASP.NET

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.

Stato dell'autorizzazione e autorizzazioni illimitate

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();

Set di autorizzazioni denominato ASP.NET

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.

Parametri di sostituzione

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

ParametroRappresenta

$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
%windir%\Microsoft.NET\Framework\{versione}\Temporary ASP.NET Files.
$CodeGen$ consente l'applicazione di autorizzazioni agli assembly generati dinamicamente.

$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.

Inizio paginaInizio pagina

Sviluppo di applicazioni Web con attendibilità parziale.

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.

Motivazioni dell'attendibilità parziale

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).

Possibili problemi

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:

System.Windows.Forms.dll

System.Drawing.dll

System.dll

Mscorlib.dll

IEExecRemote.dll

Accessibility.dll

Microsoft.VisualBasic.dll

System.XML.dll

System.Web.dll

System.Web.Services.dll

System.Data.dll

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:

L'applicazione utilizza il registro eventi o il Registro di sistema. Le applicazioni Web con attendibilità parziale non dispongono delle autorizzazioni necessarie per accedere a queste risorse di sistema. Qualora il codice invece le possieda, viene generata un'eccezione SecurityException.

L'applicazione utilizza il provider di dati OLE DB di ADO.NET per accedere a un'origine dati. Il provider di dati OLE DB richiede chiamanti con attendibilità totale.

L'applicazione chiama un servizio Web. Le applicazioni Web con attendibilità parziale dispongono di un'autorizzazione WebPermission limitata, che influisce sulla loro capacità di chiamare servizi Web in siti remoti.

Inizio paginaInizio pagina

Livelli di attendibilità

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 statoAltoMedioBassoMinimo

AspNetHosting
Livello

Alto

Medio

Basso

Minimo

DnsPermission
Illimitato

 

 

EnvironmentPermission
Illimitato
Lettura Scrittura

TEMP; TMP;
USERNAME;
OS;
COMPUTER
NAME

 

 

EventLogPermission

 

 

 

 

FileIOPermission
Illimitato
Lettura
Scrittura
Aggiunta
PathDiscovery



$AppDir$
$AppDir$
$AppDir$
$AppDir$



$AppDir$


$AppDir$

 

IsolatedStorageFilePermission
Illimitato
AssemblyIsolationByUser
UserQuota illimitato





1 MB
(può variare in base al sito)

 

OleDbClientPermission
Illimitato

 

 

 

 

PrintingPermission
Illimitato
DefaultPrinting

 

 

ReflectionPermission
Illimitato
ReflectionEmit

 

 

 

RegistryPermission
Illimitato

 

 

 

SecurityPermission
Illimitato
Asserzione
Esecuzione
ControlThread ControlPrinicipal
RemotingConfiguration













SocketPermission
Illimitato


 

 

 

SqlClientPermission
Illimitato



 

 

WebPermission
Illimitato


$OriginHost$

 

 

Inizio paginaInizio pagina

Tipi di approccio alle applicazioni Web con attendibilità parziale

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
Personalizzare i criteri per concedere all'applicazione le autorizzazioni necessarie. Ciò potrebbe essere impossibile, ad esempio, in ambienti di hosting, in cui le limitazioni dei criteri sono rigide.

Eseguire il codice con privilegi nel sandbox
Inserire il codice che accede alle risorse in un assembly wrapper, concedere l'attendibilità totale all'assembly wrapper (non all'applicazione Web) ed eseguire nel sandbox le richieste di autorizzazione del codice con privilegi.

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.

Inizio paginaInizio pagina

Personalizzazione dei criteri

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

1.

Copiare uno dei file di criteri esistenti per creare un nuovo file di criteri. Copiare ad esempio il file dei criteri dell'attendibilità media e crearne uno nuovo come indicato di seguito:

%windir%\Microsoft.NET\Framework\{version}\CONFIG\web_yourtrust.config

2.

Aggiungere le autorizzazioni necessarie al set di autorizzazioni ASP.NET nel file di criteri oppure, in alternativa, modificare un'autorizzazione esistente in modo da renderla meno restrittiva.

3.

Aggiungere una nuova mappatura <trustLevel> dopo <securityPolicy> nel file Machine.config per il nuovo file del livello di attendibilità, come illustrato di seguito:

<securityPolicy>
  <trustLevel name="Custom" policyFile="web_yourtrust.config"/>
  . . .
</securityPolicy>

4.

Configurare l'applicazione in modo che venga eseguita con il nuovo livello di attendibilità configurando l'elemento <trust> nel file Web.config dell'applicazione, come illustrato di seguito:

<system.web>
  <trust level="Custom" originUrl=""/>
</system.web>
Inizio paginaInizio pagina

Eseguire il codice con privilegi nel sandbox

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.

Schema di sandboxing

È 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.
Accertarsi che l'assembly disponga di un nome sicuro in modo da poter essere installato nella cache globale.

2.

Effettuare l'asserzione dell'autorizzazione in questione prima di accedere alla risorsa.
Ciò implica che il chiamante debba disporre dell'autorizzazione alla protezione dell'asserzione (SecurityPermission con SecurityPermissionFlag.Assertion). Le applicazioni configurate con livello di attendibilità medio o superiore dispongono di questa autorizzazione.

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.
Si consente in tal modo all'applicazione Web con attendibilità parziale di chiamare l'assembly.

4.

Installare l'assembly wrapper nella cache globale
Viene in tal modo concessa l'attendibilità totale al wrapper, ma non all'applicazione Web. I file dei criteri di ASP.NET contengono il gruppo di codice riportato di seguito, che concede l'attendibilità totale a tutti gli assembly presenti 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.

Sandboxing di codice con privilegi nel relativo assembly con asserzione dell'autorizzazione pertinente

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.

Inizio paginaInizio pagina

Scelta del tipo di approccio

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.

Personalizzazione dei criteri

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.

Sandboxing

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.

Inizio paginaInizio pagina

Attendibilità media

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

Superficie di attacco ridotta

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.

Isolamento delle applicazioni

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.

Inizio paginaInizio pagina

Limitazioni dell'attendibilità media

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

OLE DB

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.

Sandboxing per l'accesso a risorse OLE DB

Figura 9.3
Sandboxing per l'accesso a risorse OLE DB

Sandboxing

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

1.

Creare un assembly per il codice di accesso ai dati. Configurare la versione dell'assembly, attribuire a quest'ultimo un nome sicuro e contraddistinguerlo con l'attributo AllowPartiallyTrustedCallersAttribute, come descritto di seguito:

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyKeyFile(@"..\..\oledbwrapper.snk")] 
[assembly:AllowPartiallyTrustedCallersAttribute()]

Per supportare chiamanti con attendibilità parziale, è necessario specificare per tutti gli assembly con nome sicuro AllowPartiallyTrustedCallersAttribute. In questo modo si evita una richiesta in fase di linking implicita di attendibilità totale da parte di .NET Framework ogni volta che viene caricato e compilato con JIT il codice di un assembly con nome sicuro.

2.

Richiedere l'attendibilità totale. Sebbene non sia strettamente necessario, è buona prassi richiedere l'attendibilità totale, perché consente all'amministratore di vedere i requisiti di autorizzazione dell'assembly utilizzando strumenti come Permview.exe. Per richiedere l'attendibilità totale, richiedere il set di autorizzazioni illimitato, come descritto di seguito:

[assembly: PermissionSet(SecurityAction.RequestMinimum, Unrestricted=true)]

3.

Per le chiamate al database, andare a capo e utilizzare una istruzione Assert in modo da effettuare l'asserzione dell'attendibilità totale. Andare a capo ed effettuare una chiamata al corrispondente RevertAssert per invertire l'effetto dell'asserzione. Pur non essendo strettamente necessario, è comunque consigliabile inserire la chiamata a RevertAssert in un blocco finally.
Dato che il provider OLE DB richiede l'attendibilità totale, il wrapper deve effettuare l'asserzione dell'attendibilità totale. Non è sufficiente effettuare l'asserzione di un'autorizzazione OleDbPermission. Al passaggio 7 è spiegato come migliorare la protezione utilizzando CodeAccessPermission.Assert.

public OleDbDataReader GetProductList()
{
  try
  {
    // Assert full trust (the unrestricted permission set)
    new PermissionSet(PermissionState.Unrestricted).Assert();
    OleDbConnection conn = new OleDbConnection(
       "Provider=SQLOLEDB; Data Source=(local);" +
       "Integrated Security=SSPI; Initial Catalog=Northwind");
    OleDbCommand cmd = new OleDbCommand("spRetrieveProducts", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    conn.Open();
    OleDbDataReader reader = 
          cmd.ExecuteReader(CommandBehavior.CloseConnection);
    return reader;
  }
  catch(OleDbException dbex)
  {
    // Log and handle exception
  }
  catch(Exception ex)
  {
    //  Log and handle exception
  }
  finally
  {
    CodeAccessPermission.RevertAssert();
  }
  return null;
}

4.

Creare l'assembly e installarlo nella cache globale con il seguente comando:

gacutil -i oledbwrapper.dll

Per essere certi che l'assembly venga copiato nella cache globale dopo ogni rigenerazione, aggiungere la seguente riga di comando per l'evento di post-generazione (disponibile nelle proprietà del progetto in Visual Studio.NET) al progetto dell'assembly del wrapper:

"C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\gacutil.exe" 
/i $(TargetPath)

Nota: gli assembly con nome sicuro chiamati dall'applicazione o servizio Web di ASP.NET devono essere installati nella cache globale. Installare l'assembly nella cache globale in questa istanza, in modo da essere certi che gli venga concessa l'attendibilità totale.

5.

Configurare l'attendibilità media per l'applicazione Web. Aggiungere il codice riportato di seguito a Web.config oppure inserirlo in Machine.config all'interno dell'elemento <location> che si riferisce all'applicazione:

<trust level="Medium" originUrl=""/>

6.

Fare riferimento all'assembly di accesso ai dati dall'applicazione Web ASP.NET.
Dato che l'assembly con nome sicuro deve essere contenuto nella cache globale e non nella directory \bin di un'applicazione Web, è necessario aggiungerlo all'elenco degli assembly utilizzati nell'applicazione se non si utilizzano file di codice sottostante. È possibile ottenere il PublicKeyToken dell'assembly utilizzando il seguente comando:

sn -Tp oledbwrapper.dll

Nota: utilizzare l'opzione –T (in maiuscolo).

Aggiungere quindi quanto segue a Machine.config o Web.config:

<compilation debug="false" >
  <assemblies>
    <add assembly="oledbwrapper, Version=1.0.0.0, Culture=neutral,    
         PublicKeyToken=4b...06"/>
  </assemblies>
</compilation>

Nota: tra le rigenerazioni dell'assembly del wrapper può essere necessario riciclare il processo di lavoro di ASP.NET, perché l'assembly del wrapper, installato nella cache globale, viene copiato nella cache dal processo ASP.NET. Per riciclare il processo di lavoro di ASP.NET (Aspnet_wp.exe) è possibile utilizzare l'utilità IISreset.exe.

7.

Proteggere il codice che chiama Assert.
La chiamata ad Assert implica che il codice che chiama il wrapper di accesso ai dati può interagire con l'origine dati OLE DB. Per impedire che codice nocivo chiami il componente di accesso ai dati e possa servirsene per attaccare il database, è possibile inviare una richiesta completa dell'autorizzazione personalizzata prima di chiamare Assert e aggiornare il file dei criteri dell'attendibilità media per concedere l'autorizzazione personalizzata all'applicazione Web. Questa soluzione comporta un carico di lavoro ragionevole per lo sviluppatore.

Per ulteriori informazioni sulle modalità di sviluppo di un'autorizzazione personalizzata, vedere "Procedura: creare un'autorizzazione per la crittografia personalizzata" nella sezione "Procedure" di questa guida.

Registro eventi

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.

Accesso al registro 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".

Sandboxing

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

1.

Creare un assembly per il codice del registro eventi. Configurare la versione dell'assembly, attribuirgli un nome sicuro e contraddistinguerlo con l'attributo AllowPartiallyTrustedCallersAttribute, come descritto di seguito:

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyKeyFile(@"..\..\eventlogwrapper.snk")] 
[assembly:AllowPartiallyTrustedCallersAttribute()]

Per supportare chiamanti con attendibilità parziale, è necessario specificare per tutti gli assembly con nome sicuro AllowPartiallyTrustedCallersAttribute. In questo modo si evita una richiesta in fase di linking implicita di attendibilità totale da parte di .NET Framework ogni volta che viene caricato e compilato con JIT il codice di un assembly con nome sicuro.

Nota: AllowPartiallyTrustedCallersAttribute è definito nello spazio dei nomi System.Security, pertanto è necessario fare riferimento a tale spazio dei nomi con un'istruzione using.

2.

Richiedere le autorizzazioni appropriate.
Sebbene non sia strettamente necessario, è buona prassi richiedere autorizzazioni appropriate, perché ciò consente all'amministratore di vedere i requisiti di autorizzazione dell'assembly utilizzando strumenti come Permview.exe. Dato che chiamanti con attendibilità parziale possono accedere all'assembly del registro eventi, questo assembly non ha la necessità di richiedere un set di autorizzazioni con attendibilità totale. L'assembly di questo esempio semplicemente scrive nel registro eventi di un determinato computer e pertanto necessita esclusivamente della richiesta di autorizzazione indicata di seguito:

[assembly:EventLogPermissionAttribute(SecurityAction.RequestMinimum,
MachineName="<machine name>",
PermissionAccess=EventLogPermissionAccess.Instrument)]

Se tuttavia l'assembly ha la necessità di richiedere l'attendibilità totale, richiedere l'autorizzazione illimitata come descritto di seguito:

[assembly: PermissionSet(SecurityAction.RequestMinimum, Unrestricted=true)]

3.

Per le chiamate al registro eventi, andare a capo e utilizzare un'istruzione Assert per effettuare l'asserzione dell'attendibilità totale e quindi specificare il corrispondente RevertAssert per invertire l'effetto dell'asserzione. Pur non essendo strettamente necessario, è comunque consigliabile inserire la chiamata a RevertAssert in un blocco finally. Il codice riportato di seguito scrive una voce Information nel registro Applicazione contenente il testo "Writing to the event log":

try
{
  string source = "Event Source";
  string log = "Application";
  string eventText = "Writing to the event log";
  EventLogEntryType eventType = EventLogEntryType.Information;

  //Assert permission
  EventLogPermission eventPerm;
  eventPerm = new EventLogPermission(EventLogPermissionAccess.Instrument,
  "<machinename>");
  eventPerm.Assert();

  //Check to see if the source exists.
  if(!EventLog.SourceExists(source))
  {//The keys do not exist, so register your application as a source
     EventLog.CreateEventSource(source, log);
  }

  //Write to the log.
  EventLog.WriteEntry(source, eventText, eventType);
  }
  catch(Exception ex)
  {/*Handle exception*/}
  finally
  {
    CodeAccessPermission.RevertAssert();
  }

4.

Creare l'assembly e installarlo nella cache globale con il seguente comando:

gacutil -i eventlogwrapper.dll

Per essere certi che l'assembly venga copiato nella cache globale dopo ogni rigenerazione, aggiungere la seguente riga di comando per l'evento di post-generazione (disponibile nelle proprietà del progetto in Visual Studio.NET) al progetto dell'assembly del wrapper:

"C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\gacutil.exe" 
/i $(TargetPath)

Nota: gli assembly con nome sicuro chiamati dall'applicazione o servizio Web di ASP.NET devono essere installati nella cache globale. I criteri di protezione dall'accesso di codice predefinito concedono l'attendibilità totale agli assembly installati nella cache globale.

5.

Configurare l'attendibilità media per l'applicazione Web. Aggiungere quanto riportato di seguito a Web.config oppure inserirlo in Machine.config all'interno dell'elemento <location> che si riferisce all'applicazione:

<trust level="Medium" originUrl=""/>

6.

Fare riferimento all'assembly del registro eventi dall'applicazione Web ASP.NET.

Dato che l'assembly con nome sicuro deve essere contenuto nella cache globale e non nella directory \bin di un'applicazione Web, è necessario aggiungerlo all'elenco degli assembly utilizzati nell'applicazione se non si utilizzano file di codice sottostante. È possibile ottenere il PublicKeyToken dell'assembly utilizzando il seguente comando:

sn -Tp eventlogwapper.dll

Nota: utilizzare l'opzione –T (in maiuscolo).

Aggiungere quindi il codice riportato di seguito a Machine.config o Web.config:

<compilation debug="false" >
  <assemblies>
    <add assembly="eventlogwrapper, Version=1.0.0.0, Culture=neutral,
         PublicKeyToken=4b...06"/>
  </assemblies>
</compilation>

Nota: tra le rigenerazioni dell'assembly del wrapper può essere necessario riciclare il processo di lavoro di ASP.NET, perché l'assembly del wrapper, installato nella cache globale, viene copiato nella cache dal processo ASP.NET. Per riciclare il processo di lavoro di ASP.NET (Aspnet_wp.exe) è possibile utilizzare l'utilità IISreset.exe.

7.

Proteggere il codice che chiama il metodo Assert. La chiamata ad Assert implica che tutto il codice che chiama il wrapper del registro eventi può interagire con il registro eventi. Per impedire che codice nocivo chiami il wrapper del registro eventi e possa servirsene per scrivere in tale registro, è possibile inviare una richiesta completa dell'autorizzazione personalizzata prima di chiamare Assert e aggiornare il file dei criteri dell'attendibilità media per concedere l'autorizzazione personalizzata all'applicazione Web. Questa soluzione comporta un carico di lavoro ragionevole per lo sviluppatore.

Per ulteriori informazioni sulle modalità di sviluppo di un'autorizzazione personalizzata, vedere "Procedura: creare un'autorizzazione per la crittografia personalizzata" nella sezione "Procedure" di questa guida.

Servizi Web

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

1.

Configurare l'applicazione per l'esecuzione con attendibilità media.

2.

Impostare originUrl in modo che si riferisca al servizio Web che si desidera poter chiamare, come illustrato di seguito:

<trust level="Medium" originUrl="http://servername/.*"/>

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

1.

Copiare il file Web_mediumtrust.config, contenuto nella directory indicata di seguito, in un file denominato Web_mediumtrust_WebService.config, contenuto nella stessa directory.

%windir%\Microsoft.NET\Framework\{version}\CONFIG

2.

Individuare WebPermission e aggiungere un elemento <URI> per ogni server a cui accedere, come indicato di seguito:

<IPermission class="WebPermission" version="1">
  <ConnectAccess>
    <URI uri="$OriginHost$"/>
    <URI uri="http://server1/.*"/>
    <URI uri="http://server2/.*"/>
    <URI uri="http://server3/.*"/>
  </ConnectAccess>
</Ipermission>

Se si chiama il servizio Web utilizzando il relativo nome NetBIOS, nome DNS e/o indirizzo IP, è necessario disporre di un elemento <URI> distinto per ogni URI, come illustrato nell'esempio riportato di seguito.

<IPermission class="WebPermission" version="1">
  <ConnectAccess>
    <URI uri="$OriginHost$"/>
    <URI uri="http://servername.yourDomain.com/.*"/>
    <URI uri="http:// servername/.*"/>
    <URI uri="http://127.0.0.1/.*"/>
  </ConnectAccess>
</Ipermission>

3.

Salvare il file.

4.

Aggiornare il file Web.config dell'applicazione in modo che si riferisca al file dei criteri appena creato. Per ottenere questo risultato si deve creare un nuovo livello di attendibilità e mapparlo al nuovo file dei criteri. Configurare quindi l'elemento <trust> dell'applicazione in modo da utilizzare il nuovo livello.

Il brano di codice riportato di seguito mostra le aggiunte da inserire in Web.config:

<system.web>
  <securityPolicy>
    <trustLevel name="MediumPlusWebPermission" 
                policyFile="web_mediumtrust_WebService.config"/>
  </securityPolicy>
  <trust level=" MediumPlusWebPermission" originUrl=""/>
</system.web>

Utilizzo di credenziali predefinite

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.

Registro di sistema

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.

Personalizzazione dei criteri

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

1.

Copiare il file Web_mediumtrust.config, contenuto nella directory indicata di seguito, in un file denominato Web_mediumtrust_Registry.config, contenuto nella stessa directory.

%windir%\Microsoft.NET\Framework\{version}\CONFIG

Creando una copia e un file di criteri personalizzati si evita di apportare le modifiche direttamente nel file Web_mediumtrust.config. Se si modifica direttamente il file dell'attendibilità media la modifica influirà su tutte le applicazioni presenti nel computer configurate con attendibilità media.

2.

Individuare l'elemento <SecurityClasses> e aggiungere quanto segue per registrare la classe RegistryPermission:

<SecurityClass Name="RegistryPermission" 
               Description="System.Security.Permissions.RegistryPermission, 
               mscorlib, Version=1.0.5000.0, Culture=neutral, 
               PublicKeyToken=b77a5c561934e089"/>

3.

Individuare il set di autorizzazioni ASP.NET e aggiungervi l'autorizzazione RegistryPermission illimitata come indicato di seguito:

<IPermission class="RegistryPermission" version="1" Unrestricted="true" />

4.

Salvare il file.

5.

Aggiornare Machine.config per creare un nuovo livello di attendibilità da mappare al nuovo file dei criteri.

<system.web>
  <securityPolicy>
    <trustLevel name="MediumPlusRegistry" 
                policyFile="web_mediumtrust_Registry.config "/>
  </securityPolicy>

6.

Aggiornare il file Web.config in modo da configurare il livello <trust> dell'applicazione.

<system.web>
  <trust level="MediumPlusRegistry" originUrl=""/>
</system.web>
Inizio paginaInizio pagina

Riepilogo

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.

Inizio paginaInizio pagina

Risorse aggiuntive

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.


Inizio paginaInizio pagina