lucchetto sicurezzaDopo un periodo di tempo non proprio breve vorrei ricominciare, o meglio ripartire, con la mia serie di post relativi alla sicurezza nel mondo .NET. Vorrei comunque concedermi il tempo di ringraziare tutte le persone che leggono, ed apprezzano, i post che vengono trattati in questo blog. Grazie.





In security 26,27,28 andremo a parlare delle permissions e di altri concetti molto interessanti del mondo .NET Security.

Come tutti sappiamo, una permission è una classe che definisce cosa una entità può e non può fare. Come si può notare dal codice che segue: questa classe deve implementare l'interfaccia IPermission, la quale è presente nello spazio di nomi System.Security.

// Sec 25 | Code 0.1
using System.Security;
public class BlogPermission : IPermission()

Nel nostro caso, BlogPermission permette, o nega, l'accesso alle informazioni relative ad un oggetto Blog. Vedremo questa classe funzionare negli esempi di codice che seguiranno.

.NET definisce tre tipologie di permissions:

  • Code Access Permissions. Queste permissions permettono al codice di accedere a differenti risorse, come files (FileIOPermission), UI (UiPermission) ed utilizzare reflection su i componenti che la compongono (ReflectionPermission).
  • Identity permissions. Queste permissions permettono al codice di eseguire operazioni basate sulla evidence che essi presentano
  • Role base Security Permission. Composta da un unica classe (PrincipalPermission) permette l'accesso a risorse basandosi sull'identità corrente.

Eseguire le Richieste
Dopo aver introdotto velocemente il funzionamento delle permissions, iniziamo a vedere con qualche esempio come esse funzionano realmente. E' bene subito specificare che esistono due metodologie per accedere ad una risorsa definita.

  1. Dichiarativa
  2. Imperativa

Credo che il codice possa meglio spiegare realmente la differenza tra questi due mondi differenti.

[assembly: FileIOPermissionAttribute(SecurityAction.RequestMinimum,
   Read=@"c:\AppuntiBlog\CartellaPostSicura")]
[assembly: FileIOPermissionAttribute(SecurityAction.RequestRefuse,
   Read=@"c:\AppuntiBlog\CartellaPostNonSicura")]
namespace AlessioMarziali.DotNetSecurity.BlogPost
{
   
public class BlogPostPermissionsTest {}
}

Mentre la contropartita in Imperativa si traduce in questo modo

public class BlogPostPermissionsTest : Directories
{
    
public void LeggiCartellaSicura(string FileName)
    {
        FileIOPermission ioPerm = 
new FileIOPermission(FileIOPermissionAccess.Read, @"c:\AppuntBlog\CartellaPostSicura");
        ioPerm.Demand();
        
        FileStream fs = 
new FileStream(@"c:\AppuntBlog\CartellaPostSicura\" + FileName,FileMode.Open);
        fs.Close();    
    }
    
    
public void LeggiCartellaNonSicura(string FileName)
    {
        FileIOPermission ioPerm = 
new FileIOPermission(FileIOPermissionAccess.Read, @"c:\AppuntiBlog\CartellaPostNonSicura");
        ioPerm.Deny();
        
        FileStream fs = 
new FileStream(@"c:\AppuntiBlog\CartellaPostNonSicura\" + FileName,FileMode.Open);
        fs.Close();    
    }
}

Tecnicamente i due differenti approcci provocano lo stesso risultato. Evitare l'accesso del client a cartelle archiviate come non sicure. Tuttavia esiste una certa differenza tra i due approcci appena proposti. Vediamoli.

Gli attributi; con questi si può specificare che tipologia di accesso si vuole alla risorsa specifica. Per esempio, il primo snippet introdotto,  fa uso di RequestMinimum e RequestRefuse appartenenti all'enumeratore SecurityAction. Lo stato RequestMinimum sta per : "Per tutto il codice contenuto nell'assembly è necessario avere questa permission". (ndr Parlo a livello di assembly perchè tutti gli stati RequestXXXX possono essere attivi solo a livello di assembly). Se per qualunque motivo questo non può essere assicurato, nessuno del codice scritto funzionerà. Quindi, come si può ben capire, lo stato RequestRefuse esegue tutto l'opposto, ovvero : "Nessun codice dell'assembly può avere questa permission".

Per completare la serie di Richieste possibili su Permissions, parliamo di RequestOptional. Sicuramente la più atipica di tutte. Se, durante una elaborazione si tenta di accedere ad una risorsa andando a fare uso di una permissions che non è stata garantita, viene sollevata una eccezione, questa permissions tenterà di trovare una strada alternativa per eseguire l'operazione. Non è sicuramente possibile fare tutto quello che si vuole con RequestOptional, ma l'idea di eseguire dei walk around non mi è mai piaciuta tanto. Non solo. I Security Check che vengono eseguiti con RequestOptional richiedono "tempo", tempo = performance.

Può sicuramente essere utile sapere che tipo di Security Permissions (di tipo dichiarativo) vengono richieste da un assembly .NET. Per fare questo è possibile eseguire l'utility introdotta dal .NET Framework SDK permview. (ndr E' possibile fare anche il dump su un file di testo)

permview /decl IlMioSuperSicuroAssembly.dll