Versione per la stampa      Invia     
Valuta il contenuto e lascia un commento
TechNet
TechNet Library
Articoli tecnici
Sicurezza
 La sicurezza arriva da .NET Framewo...
La sicurezza arriva da .NET Framework

Seconda parte

Da Raffaele Rialdi

Nella prima parte dell'articolo ho cercato di spiegare come il Framework.NET fornisca nuovi potenti strumenti ai sistemisti per "difendersi dalle applicazioni". In questa seconda parte prenderò in esame l'aspetto operativo. Per facilitare la comprensione dei termini indicherò tra parentesi la nomenclatura in lingua inglese che molto spesso è quella installata sui server.

Le policy di sistema

Il Framework.NET ha quattro livelli di gestione delle policy di sicurezza:

  • Enterprise

  • Computer (Machine)

  • Utente (User)

  • Application Domain

Per ciascuno di queste policy è possibile stabilire un binomio importante: gli assembly soggetti ad un insieme di permission e le permission a cui gli assembly devono essere sottoposti. Non prenderò in esame la policy Application Domain perché questa può essere imposta solo da applicazioni (come ad esempio ASP.NET) che volessero isolare altri assembly (operazione chiamata anche sandboxing), caratteristica comunque molto interessante per i programmatori che debbano usare assembly di terze parti.

È importante avere a disposizione policy diverse perché l'amministratore può decidere se il binomio debba essere applicato nel contesto dell'utente (User) piuttosto che del singolo PC (Machine) oppure dell'intero dominio di Active Directory (Enterprise).

Le autorizzazioni effettive attribuite all'assembly vengono determinate dal risultato dell'intersezione delle autorizzazioni ottenute in ciascuna policy. In altre parole significa che vengono applicati i permessi più restrittivi presenti nelle quattro policy. Perció se ad esempio un'azienda vuole limitare l'uso di un certo assembly su un PC a disposizione del pubblico, sarà sufficiente configurare la restrizione solo nella policy di quel Computer. La procedura è del tutto analoga per limitare l'accesso a certe risorse quando l'assembly venisse usato da un particolare utente.

Policies

La configurazione della code access security si effettua con lo strumento Configurazione di Microsoft .NET Framework il (.NET configuration tool) installato negli strumenti di amministrazione dal Framework.NET.

NETConfigMenu

La voce Criteri di protezione runtime (Runtime Security Policy) è quella che riguarda la Code Access Security Policy, e sotto questa voce sono presenti i rami che rappresentano le tre policy di sistema.

I set di autorizzazioni (permission set) predefiniti

Come si evince dal configuratore, i tre rami propongono tutti i medesimi elementi con l'eccezione di Computer dove sono già predefiniti diversi Gruppi di Codice.

PermissionSet

I set dei autorizzazioni (permission sets) sono dei modelli che stabiliscono quali azioni possono essere compiute dagli assembly. Il Framework.NET ne mette a disposizione sette che rispondono alle esigenze più comuni:

  • FullTrust. Gli assembly che hanno FullTrust non vengono monitorati dalla Code Access Security. Al vantaggio di non subire alcun calo di performance necessario al controllo si contrappone la totale libertà di azione che il codice managed potrà esercitare al pari del vecchio codice unmanaged.

  • SkipVerification. Permette all'assembly di non sottostare alla verifica della Code Access Security.

  • Execution. Permette all'assembly di essere eseguito.

  • Nothing. Serve a negare qualsiasi tipo operazione o accesso a risorse protette. Si rivela molto utile per arginare applicazioni che sono note per dare problemi.

  • LocalIntranet. Un insieme di permessi ristretti che sono assegnati di default ai gruppi di codice che vengono lanciati con i nomi UNC (\\server\percorso\) o scaricati dal sito Intranet. Tra le varie autorizzazioni negate c'è ad esempio l'accesso al file system; per rispondere alle necessità dell'applicazione è concesso invece l'utilizzo dell'isolated storage (un piccolo spazio su disco riservato esclusivamente all'applicazione soggetta alla restrizione). Internet. Un insieme di permessi ancora più restrittivi applicato di default alle applicazioni che vengono avviate da un dominio diverso da quello a cui appartiene il PC. Queste restrizioni sono molto elevate e permettono di avviare in tutta sicurezza un exe da Internet (anche privo di certificato digitale) senza poter subire alcun danno. Le poche operazioni consentite permettono all'utente di usufruire di un'elaborazione dati più ricca (quello indicato come rich client nella prima parte dell'articolo) rispetto alla classica pagina web.

  • Everything. Everything concede tutti i permessi all'applicazione. L'unica differenza con FullTrust è che la Code Access Security sottopone comunque l'applicazione al controllo delle operazioni eseguite (cioè non possiede il permesso a SkipVerification).

Poiché i permessi predefiniti non sono editabili, per vederne il contenuto è sufficiente duplicare il set (col menu contestuale) e quindi editare la copia.

Definizione di un nuovo set di autorizzazioni

In aggiunta al set di permessi predefiniti, il Framework.NET consente la definizione di nuovi set. Supponiamo ad esempio di aver ricevuto il file Caramelle.exe da uno sconosciuto. Il programmatore ci informa che una parte del suo applicativo ha bisogno di accedere a c:\ ma non alle sottocartelle. Il primo passo da eseguire è di creare un nuovo set di permessi che vincoli in modo molto rigido l'applicativo.

Dal menu contestuale della cartella Set di autorizzazioni scegliamo la voce "nuovo" per avviare il wizard:

NewPermission1

Dopo aver inserito nome e descrizione si procede a scegliere i permessi da concedere:

NewPermission2

Per prima cosa è necessario dare il diritto di esecuzione all'applicazione scegliendo protezione (security) ed il solo flag di "Attiva esecuzione assembly"

NewPermission2

Inoltre, poiché l'applicativo possiede un'interfaccia utente, è necessario dargli il relativo permesso. Per brevità nell'esempio forniamo accesso completo all'interfaccia utente nonostante esista la possibilità di limitare una serie di operazioni considerate a rischio come scrivere negli appunti (clipboard).

NewPermission4

Infine tramite la voce "I/O file" diamo il permesso di accesso alla sola cartella c:\ evitando di spuntare la voce "ricerca percorso" che permette di indicare se propagare il permesso alle sottocartelle.

NewPermission5

I gruppi di codice (code group) predefiniti

La sola policy che possiede dei gruppi di codice predefiniti (All_Code a parte che comprende qualsiasi assembly) è Computer. All'interno delle policy ci sono i gruppi di codice che servono ad identificare uno o più assembly e a stabilire a quali set di permessi essi dovranno sottostare. Così come per i set di autorizzazioni, è possibile definire nuovi gruppi in aggiunta a quelli predefiniti nelle policy.

PolicyTree

Poiché possono esistere più gruppi di codice e un assembly può far parte di più gruppi, l'assembly riceverà i permessi più ampi dei gruppi di cui fa parte. In altre parole viene fatta l'unione (o la somma se preferite) delle autorizzazioni di tutti i gruppi di cui fa parte. È importante non confondere questa operazione di unione (all'interno di una policy) con quella descritta in precedenza che interseca le autorizzazioni delle quattro policy nel sistema o se preferite che prende il minimo comun denominatore delle operazioni di unione nelle quattro policy.

PoliciesUnion

Definizione di un nuovo gruppo di codice

Tornando all'esempio dell'assembly Caramelle.exe, creiamo ora un nuovo gruppo specifico. Dal menu contestuale di All_Code avviamo il wizard con la voce Nuovo e compiliamo le due voci Nome e Descrizione. Il nome Caramelle che stiamo attribuendo al gruppo di codice è arbitrario e non ha alcuna relazione con il nome dell'assembly Caramelle.exe.

CodeGroup2

Il passo successivo serve a definire l'evidence cioè il criterio secondo il quale il Framework.NET potrà distinguere Caramelle.exe da un altro assembly.

CodeGroup2
  • Tutto il codice (All Code). Non viene fatto alcun filtro e qualsiasi assembly ricadrà nel gruppo definito con questa condizione.

  • Directory dell'applicazione (Application Directory). A questo gruppo di codice appartengono tutti gli assembly che risiedono nella cartella o in una sottocartella dell'applicazione che li ha caricati. A questi assembly verranno assegnate le corrispondenti autorizzazioni.

  • Hash. L'hash è un codice che viene calcolato sulla base dell'immagine binaria dell'assembly. Che due assembly diversi generino lo stesso hash è possibile ma è altamente improbabile. In mancanza di altri meccanismi questo sistema può essere un'ottima soluzione. Uno degli svantaggi è che versioni diverse dello stesso applicativo avranno hash differenti e di conseguenza la configurazione della nuova versione dovrà essere ripetuta.

  • Editore (Publisher). Il gruppo la cui condizione di appartenenza è l'editore specificato in un certificato X.509 (Authenticode), identifica tutti gli assembly da lui pubblicati. Quando l'assembly viene firmato con un certificato digitale, è possibile filtrare nel gruppo tutti gli assembly che sono stati pubblicati da un certo autore.

  • Sito (Site). Identifica tutti gli assembly che provengono da un certo sito http, https o ftp.

  • Nome Sicuro (Strong Name). Il nome sicuro è facilmente generabile dallo sviluppatore (utility sn del Framework.NET SDK) ed ha il grosso vantaggio di identificare in modo univoco gli assembly che vengono contrassegnati. Per identificare un assembly in particolare il configuratore può specificare il suo nome e la versione.

  • URL (URL). Tutti gli assembly che vengono scaricati dall'URL indicato fanno parte di questo gruppo di codice. È possibile indicare anche il protocollo file: per indicare un generico percorso locale o di rete. Può essere specificato sia un URL completo del nome dell'assembly che un URL parziale che termina con l'asterisco: http://www.website.org/download/*;

  • Zona (Zone). Una delle zone definite da Internet Explorer: Internet, Intranet locale, Risorse del computer, Siti attendibili, Siti non attendibili.

Il nome sicuro è un ottimo sistema per filtrare tutti gli assemby prodotti da un'azienda che dovrebbe sempre usare lo stesso nome sicuro per tutti gli assembly prodotti. Tra i gruppi di codice della policy Computer sono presenti due importanti gruppi: Microsoft ed Ecma. Questi due gruppi permettono di assicurare ai prodotti Microsoft ed Ecma lanciati dai dischi locali il diritto al FullTrust, anche nel caso in cui i permessi su My_Computer_Zone venissero ridotti.

Poiché abbiamo chiesto al programmatore di compilare l'assembly con il suo "nome sicuro", sarà questa la scelta effettuata per Caramelle.exe.

CodeGroup3

Grazie al pulsante Importa, possiamo selezionare l'eseguibile e il wizard ricaverà automaticamente le informazioni necessarie.
L'ultimo passo è quello di scegliere il set di autorizzazioni a cui associare il nuovo gruppo. Le autorizzazioni scelte saranno quelle definite precedentemente sotto il nome "C_FileSystem".

CodeGroup4

A questo punto si presenta un problema di logica. Poiché la Code Access Security esegue l'unione di tutti i gruppi definiti e Caramelle.exe ricade anche nel gruppo My_Computer_Zone che ha accesso incondizionato, la definizione appena eseguita non ha alcun effetto.

Policy

Gruppo di codice valido per Caramelle.exe

Autorizzazioni assegnate

Enterprise

All_Code

FullTrust

Utente

All_Code

FullTrust

Computer

All_Code

Nothing

Computer

My_Computer_Zone

FullTrust

Computer

Caramelle

C_FileSystem (solo c:\)

Quando la Code Access Security valuta l'appartenenza ai gruppi di codice, esamina un livello alla volta cominciando da All_Code a cui appartengono tutti gli assembly. Solo i rami figli dei gruppi di codice la cui condizione è soddisfatta saranno esaminati. Perciò in questo esempio il gruppo di codice Intranet_Same_Site_Access non viene analizzato perché l'assembly non appartiene al gruppo LocalIntranet_Zone.

Nella policy Computer viene fatta l'unione di Nothing, FullTrust e C_FileSystem e il risultato è ovviamente FullTrust. L'intersezione del FullTrust appena ricavato in Computer con gli altri due FullTrust in Enterprise e Utente daranno pieno accesso all'assembly. Questa sarebbe la corretta conclusione della procedura se avessimo voluto concedere ad un certo nome sicuro (per esempio quello aziendale) i pieni diritti, indipendentemente dalla zona di appartenenza dell'assembly (Internet, Intranet, ...).

Noi vogliamo invece ottenere che nella policy Computer venga preso in considerazione il solo gruppo di codice Caramelle che limiterà le autorizzazioni al solo set chiamato C_FileSystem. Questo comportamento lo si ottiene dalle proprietà del gruppo di codice Caramelle, selezionando la voce "Il livello di criteri disporrà solo delle autorizzazioni relative al set associato a questo gruppo di codice" mostrata in figura.

CodeGroup5

Questa impostazione deve essere specificata quando si vuole limitare un assembly alle autorizzazioni specificate. Se tuttavia si procede con l'atteggiamento inverso, cioè quello di garantire un minimo set di autorizzazioni, questa impostazione non dovrà essere specificata perché l'operazione di unione provvederà a fornire il set più ampio di autorizzazioni.

L'opzione "I livelli dei criteri al di sotto di questo livello non verranno valutati" serve ad indicare che si vogliono escludere dall'operazione di intersezione le autorizzazioni per le policy successive a quelle in esame. I livelli vengono infatti esaminati nella sequenza Enterprise, Computer, Utente e Application Domain. Se questa opzione viene ad esempio specificata in Enterprise, le condizioni espresse nelle altre policy saranno ignorate.

È importante notare che il set di autorizzazioni specificato per All_Code nella policy Computer (Machine) è Nothing mentre nelle policy Enterprise e Utente (User) è FullTrust. Se il set di autorizzazioni per All_Code in Computer fosse FullTrust, ogni altra dichiarazione specificata in quella policy sarebbe inutile poiché le autorizzazioni all'interno di una policy sono l'unione di tutti i gruppi di codice dichiarati.

Allo stesso modo, se il set di autorizzazioni di All_Code in Enterprise o Utente fosse Nothing, e visto che All_Code è l'unico gruppo di codice specificato in quelle policy, nessun assembly riceverebbe permessi. Questo perché i permessi totali sono l'intersezione di quelli calcolati in ciascuna policy (e se si interseca Nothing con qualsiasi altra cosa il risultato sarà sempre Nothing).

Code Access Security (CAS) in azione

Una volta effettuate le configurazioni, al successivo lancio l'assembly Caramelle.exe sarà soggetto alle restrizioni delle autorizzazioni impostate. Ho progettato l'applicazione Caramelle per eseguire l'accesso a sei tra le risorse sensibili più utilizzate. Caramelle.exe può contenere qualsiasi tipologia di codice, ma solo quello concesso nelle policy potrà essere eseguito sul PC, grazie al controllo che la CAS effettua durante la fase di runtime.

Cliccando i pulsanti, le risorse sensibili vengono accesse. Se questo ha esito positivo viene stampato OK, altrimenti viene stampato il nome della permission che la Code Access Security ha rifiutato.

Caramelle_FileOK

Analogamente con quanto fatto su disco, è possibile concedere accesso ad altre risorse come il registry o le comunicazioni via winsock. Da notare che l'accesso alle comunicazioni winsock sono inibite dall'accesso alla risoluzione DNS prima ancora che al tentativo di apertura del canale di comunicazione.

Supponendo di concedere a Caramelle.exe le autorizzazioni sul registro, DNS e winsock (selezionando le opzioni in basso, vicine ai pulsanti OK e Annulla):

Permission_Registry

Permission_winsock

il risultato sarebbe il seguente:

Caramelle_FileRegDnsWinsockOK

Test su un assembly sconosciuto

Un altro importante wizard è presente nella configurazione del Framework.NET è quello che permette di valutare un assembly. Dal menu contestuale di Criteri di protezione runtime (Runtime Security Policy) mostrato all'inizio si sceglie Valuta Assembly (Evaluate Assembly) e si seleziona l'assembly da controllare. Ci sono due possibilità: la prima è quella di verificare quali sono le autorizzazioni assegnate all'assembly; la seconda è quella che mostra a quali gruppi di codice l'assembly appartiene. Il filtro sulle policy permette di eseguire una diagnostica ancora più puntuale, operazione molto utile in presenza di configurazioni complesse.

Questo strumento si dimostra estremamente efficace per valutare se la configurazione della sicurezza è stata fatta correttamente, specie quando l'esecuzione dell'assembly senza un opportuno controllo può rivelarsi fatale.

Evaluate

Deploy con Active Directory

Sempre dal menu contestuale di Criteri di protezione runtime (Runtime Security Policy) è possibile creare un package di setup per le impostazioni che si vogliono distribuire in rete. Il wizard, che può esportare una delle tre policy presenti nello strumento di amministrazione, crea un file in formato .MSI. A questo punto ci sono due possibilità: procedere ad un deploy manuale, soluzione valida per un ristretto numero di PC, oppure il deploy in Active Directory. Quest'ultima soluzione è molto semplice e consiste nell'aprire la gestione utenti di Windows 2000/2003 Server, selezionare una Organizational Unit, e associargli il package .MSI.

Clicca pe ingrandire l'immagine Deploy

Conclusione

Ho trovato molto affascinante il fatto di poter selettivamente inibire l'accesso a risorse delicate come il registry, il file system o un database senza alcuna conoscenza del codice che viene eseguito. Come programmatore mi affascina ancor di più la possibilità di estendere le autorizzazioni. È così possibile definire, per esempio, in un impianto industriale un nuovo set di autorizzazioni per l'accesso ai macchinari semplicemente installando in "Assembly dei criteri" ("Policy Assemblies") l'assembly che definisce le nuove regole di gestione di questa risorsa. Autorizzazioni che potranno essere usate nella definizione dei gruppi di codice così come abbiamo fatto per quelle predefinite.

In questi due articoli ho cercato di evidenziare i punti salienti di un argomento che richiederebbe approfondimenti ben più ampi. Non ho parlato, per esempio, dello strumento CasPol che, per gli appassionati degli script e dei batch, consente da comando di riga di effettuare tutte le operazioni realizzate dalla management console grafica. Omissione che risulta però poco rilevante visto che CasPol e il configuratore grafico del Framework condividono la stessa logica di funzionamento ed agiscono sugli stessi file xml di configurazione.

Con la Code Access Security si apre una nuova strada per la gestione sicura dei sistemi informatici. Certo sarà necessario del tempo prima che in ambiente Windows il codice sia esclusivamente sotto il controllo del Framework.NET, però questa è l'unica tecnologia che al momento consegna così tanto potere nelle mani dell'amministratore di sistema.

Per il futuro credo che la Code Access Security sarà l'unica risposta possibile ad adware, malaware, spyware e virus e potremo finalmente accettare Caramelle.exe dagli sconosciuti.

© 2008 Microsoft Corporation. Tutti i diritti riservati. Condizioni per l'utilizzo  |  Marchi  |  Informativa sulla privacy
Page view tracker