Dopo aver parlato, poco tempo fa, di caspol.exe e di come .NET implementa alcune
logiche di sicurezza, voglio descrivere un attimo una cosa che mi ha fatto
perdere parecchio tempo per evidente ignoranza della questione. Ovvero (può
sembrare
banale), come revocare permessi ad un'applicazione.
Lasciatemi descrivere lo scenario in cui voglio ambientare la mia
spiegazione. Supponiamo di prendere la nostra applicazione
ReadRegistry che abbiamo creato a suo tempo e di farla girare da una qualsiasi directory
del nostro PC. Abbiamo detto che trattandosi di un EXE eseguito da un disco
locale, questo assembly gira nella My_Computer_Zone. In questo
caso, quindi, l'assembly gira come FullTrust. Di questo abbiamo
già parlato: se vi siete persi qualcosa, andate a leggere i miei post
precedenti.
Tutto questo è molto bello, però io mi sono posto la seguente
domanda:
se io volessi revocare i permessi alla mia
applicazione, cosa devo fare?
Ci tengo a rispondere a questa domanda, perchè io non la
trovo così banale, soprattutto perchè fino ad adesso ho omesso (più o meno
volutamente) un concetto importante. Arriviamo al dunque: aprite il tool
.NET Framework 1.1 Configuration e date un'occhiata ai
5 Code Group built-in. Come abbiamo fatto noi
precedentemente, possiamo ovviamente definire code groups aggiuntivi,
personalizzati, custom, insomma. Ogni code group può appartenere ad uno
qualsiasi dei 5 code group predefiniti: nel tool appariranno come indentati
rispetto al code group corrispondente. Esattamente come abbiamo fatto noi
l'altra volta: ovvero, per dare dei permessi speciali al nostro assembly,
abbiamo dovuto creare un code group tutto nostro dentro la
LocalIntranet_Zone.
A questo gruppo, che avevamo chiamato "ReadRegistry", abbiamo assegnato
i permessi di FullTrust.
Non è
propriamente esatto.
In realtà, i
permessi assegnati ad un group equivalgono alla "somma" dei permessi di
tutti i code group incontrati durante l'esplorazione dell'albero: scusatemi, ma
non so spiegarmi meglio! Adesso facciamo la prova del 9 (ma è vero che la
prova del 9 a volte può fallire?) e sarà tutto più chiaro.
Revochiamo un permesso, ma l'assembly gira senza
problemi. PERCHE'?
Quello che vogliamo fare è togliere i permessi di
lettura dal registry alla nostra applicazione, anche se quest'ultima gira dal
nostro disco C: (quindi, My_Computer_Zone). Se avete ancora aperto .NET
Framework 1.1 Configuration, è il momento di agire.
Andate nel nodo Permission Sets, duplicate il set chiamato
FullTrust e rinominatelo come FullTrust_NoRegistry.
Cliccate con il pulsante destro, selezionate Change
Permissions, selezionate la voce Registry, cliccate
sul pulsante Add. Non date alcun permesso: il nostro assembly non
deve assolutamente avere alcun permesso sul registry. Cliccate semplicemente su
Ok per chiudere la finestra di dialogo. Fine prima
parte.
Adesso create un nuovo code group dentro il code group
My_Computer_Zone, chiamatelo NoRegistry. La membership
condition sarà quella di avere lo
strong name del nostro assembly. Il permission sets sarà quello appena creato, ovvero
FullTrust_NoRegistry. Fine seconda ed ultima parte del test.
Cosa ci aspettiamo? Anche se l'applicativo gira da C:
continua a funzionare regolarmente, senza sollevare alcun exception. Perchè?
Il motivo sta tutto nella frase criptica
che ho detto prima: i permessi associati al nostro assembly sono
FullTrust + FullTrust_NoRegistry: il primo è dato dal nodo
My_Computer_Zone, il secondo dal nodo NoRegistry. Ecco spiegato il motivo per
cui l'assembly non dà alcun messaggio di errore. Ovvero...
Ogni code group eredita anche i permessi dei code groups
padri.
Revochiamo veramente il permesso
Tornate nel tool
.NET Framework 1.1 Configuration, andate nelle properties del nostro code group
NoRegistry. Nella finestra di dialogo ci sono due check-box di
cui non abbiamo mai parlato.
- This policy level will only have the permissions
from the permission set associated with this code group
Se è attivo, blocchiamo questo processo di
"ereditarietà" che ho appena descritto. Se un assembly appartiene a questo code
group, all'assembly vengono assegnati i permessi specificati dal code group,
senza considerare i padri. Equivale all'opzione -exclusive
del comando
caspol.exe.
- Policy level below this level will not be
evaluated
Se è attivo e se un assembly
appartiene a questo code group, all'assembly vengono assegnati i relativi
permessi, evitando di valutare i code group figli. Equivale all'opzione
-levelfinal
del comando caspol.exe.
Per ottenere veramente quello che vogliamo, quindi, ci
basta abilitare il primo checkbox. Proviamo ad eseguire ReadRegistry.exe. Questa
volta all'assembly viene assegnato il permission sets denominato
FullTrust_NoRegistry : ovvero, tutti i permessi possibili ed immaginabili,
tranne l'accesso al registry.
E questa volta, finalmente, abbiamo l'exception che ci aspettiamo!!!
Conclusioni
Scrivere un intero articolo per ottenere
un'exception non è granchè, vero?
Abbiamo dimostrato però che anche se
un'applicazione gira dalla My_Computer_Zone, possiamo comunque
limitare le sue possibilità, assegnando e revocando permessi come meglio
crediamo. Notare che caspol.exe e il tool relativo contengono tutta una serie di
permessi piuttosto interessanti: rete, accesso ad Internet, UI, Reflection,
possibilità di stampare, etc. Tutto questo (anche se credo che poi pochi lo
faranno realmente) per creare permission sets piuttosto "mirati" per le nostre
applicazioni Windows Forms.