Code Access Security Raffaele Rialdi MVP C# [email protected] http://mvp.support.microsoft.com MVP Profile: http://snipurl.com/7vyf Il modello di sicurezza in "NT" Autenticazione utenti Applicazioni girano usando un account utente (token) Utenti e Gruppi possono essere organizzati in gruppi Ai gruppi o agli utenti possono essere assegnati o tolti permessi per accedere a risorse (NTFS, rete, device, etc.) Per il codice (Activex, VBA, ...) il sistema è quello di: firmare con un certificato X509 fidandosi ciecamente del programmatore che l'ha firmato chiedere all'utente finale la conferma ... risultato = disastro Perché la CAS è un 'must' IE può ospitare all'interno della pagina HTML dei controlli Winform la CAS può far girare questi controlli senza alcuna richiesta all'utente La stessa cosa vale per intere applicazioni o solo assembly scaricati da internet La CAS è fondamentale per chi scrive controlli ("Least Privilege Model") La CAS dà agli admin un potere che mai hanno avuto prima Limita ciò che può essere eseguito nel codice Proteggere il PC da codice di provenienza incerta (spyware, adware, malaware, virus, worm, ...) Impedire selettivamente che del codice possa accedere a certe funzionalità dell'OS CAS: a cosa non serve Non è un sistema di protezione del software contro gli hacker Non è un sistema che autorizza l'uso del software sotto licenza Protegge l'utente che usa il software solo se vuole essere protetto (admin può disabilitare la CAS ...) Questione di punti di vista ... NT Esecuzione Autorizzazione Permission User Token ACL Evidence Autenticazione Codice CAS Autenticazione Risorsa Autorizzazione La difficoltà sta nel... glossario Evidence Strong name Code Group Full trust Partial trust Security Policy Permission Permission Set Stack Walk Assert Demand ... Prove di protezione Nome sicuro Gruppi di codice Attendibilità totale Attendibilità parziale ... Autorizzazioni Set di autorizzazioni ... ... ... ... Configurazione della CAS Si esegue tramite CasPol (command line) oppure tramite il Framework Configuration Tool Security Policy Code Groups Permission Set Policy Assemblies Permission: "cosa vuoi fare?" (autorizzazione) I permessi sono le autorizzazioni ad eseguire una certa operazione Il framework ne predefinisce un certo numero I permessi definiti nella CAS sono trasversali a quelli più noti come NTFS, SQL, etc. Per ciascun permesso è possibile definire dei valori molto dettagliati È possibile costruire dagli admin tool o programmaticamente un gruppo di permessi chiamato Permission Set Evidence: "chi sei?" (autenticazione) Evidence è la prova oggettiva per sapere di chi è o da dove proviene il codice managed La CAS può identificare un assembly basandosi su: Cartella dove risiede Sito o Url da cui viene scaricato Zona in cui si trova Strong Name presente nel suo manifest Hash dell'assembly Firma digitale (Authenticode, stessa degli Activex) Al caricamento dell'assembly in memoria, viene subito ricavata l'evidence È possibile da codice associare una evidence ad un AppDomain in modo da isolare degli assembly Code Group e Security Policy I Code Group sono l'associazione di un evidence con un insieme di permessi Una Security Policy è una collection di Code Group Evidence Permission Set Al runtime viene fatto il calcolo dei permessi effettivi 1. Unione 2. Intersezione void SetAppDomainPolicy(PolicyLevel domainPolicy); MA ... in configurazioni complesse non sempre l'unione è esaustiva di quello che vorremmo Exclusive Level Final Come gestire la CAS da codice? Lo strumento principale sono le classi xxxPermission e relativi attributi che permettono di chiedere alla CAS di eseguire controlli e, se necessario lanciare la SecurityException PermissionSet ISecurityEncodable IStackWalk CodeAccessPermission IPermission FileIOPermission UIPermission EnvironmentPermssion FileIOPermission Attribute UIPermission Attribute EnvironmentPermssion Attribute CodeAccessPermission Attribute Demand, LinkDemand, InheritanceDemand disponibile anche come attributo verifica il permesso richiesto eseguendo lo stack walk notare che Metodo4 non è soggetto ad alcun controllo permission Metodo2 negata LinkDemand Metodo1 Demand solo come attributo verifica il permesso richiesto solo sul chiamante senza eseguire stack walk il controllo viene eseguito dal jitter InheritanceDemand solo come attributo verifica il permesso richiesto sulle classi che derivano da quella su cui è applicato l'attributo il controllo viene eseguito al load SecurityException Stack walk Metodo3 OK Stack walk Metodo4 Demand // Richiesta imperativa ... FileIOPermission perm = new FileIOPermission( FileIOPermissionAccess.AllAccess, @"c:\"); perm.Demand(); // ... oppure dichiarativa (sull'assembly) [assembly:FileIOPermission( SecurityAction.Demand, All = @"C:\") ] RequestMinimum, RequestOptional, RequestRefuse Disponibili solo nella versione Attribute Applicabili solo all'intero Assembly RequestMinimum. La permission indicata è indispensabile per l'assembly altrimenti l'assembly non viene caricato. RequestOptional. Permessi aggiuntivi rispetto al minimo indispensabile. Vengono dati all'assembly solo se disponibili. RequestRefuse. Permessi che questo assembly decide di togliersi per evitare di essere usato da codice malicious. Tip: Se sono specificati RequestOptional e RequestRefuse allora verranno attribuiti all'assembly solo quei permessi anche se le policy sono più alte. Se le Minimum sono inferiori alle Policies SecurityException Se sono specificate solo le Minimum Perm = Policies - Refused Se sono specificate le Optional Perm = Policies (Optional Minimum) - Refused Il tool PermView permette di vedere nell'assembly i requisiti di security Assert, Deny e PermitOnly ... ... come modificare lo stack walk Metodo1 Assert e RevertAssert Deny e RevertDeny Impediscono che la richiesta di permesso si propaghi ai chiamanti Assert si chiama al più tardi e RevertAssert al più presto Utile per evitare perdite di performance dovute al controllo della CAS Metodo2 permission negata Metodo3 Assert OK Stack Metodo4 walk Demand Impedisce che tutti i metodi chiamati da questo possano accedere alla risorsa (...) PermitOnly e RevertPermitOnly Permette a tutti i metodi chiamati da questo di poter accedere solo alla risorsa specificata (...) Gli stack walk modifiers vengono rimossi automaticamente alla fine del metodo che li chiama oppure chiamando esplicitamente il corrispondente Revert Nota: Deny e PermitOnly si usano su un metodo chiamante mentre RequestRefuse solo sull'assembly chiamato PermissionSet È possibile costruire via codice un permission set // Costruzione di un permission set PermissionSet ps1 = new PermissionSet(PermissionState.None); ps1.AddPermission(new FileDialogPermission(FileDialogPermissionAccess.Open)); ps1.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, Path.GetFullPath("UnFile.txt"))); ps1.Demand(); Si possono fare Demand, Deny, Assert, PermitOnly Si possono eseguire operazioni insiemistiche (unione, intersezione, test di subset, ...) Si può serializzare con ToXml e FromXml Nella SecurityException è presente la proprietà PermissionType che indica qual'è il permesso mancante. Alcune volte le info dentro SecurityException sono povere ma nel fw 2.0 è stato posto rimedio. Strong Name Lo strong name dovrebbe essere "aziendale" e ben custodito Esegue una sorta di "firma" sull'assembly Le specifiche ECMA raccomandano l'uso dello strong name solo per il versioning e MAI per sicurezza Esistono sistemi per ingannare il CLR e far caricare un Assembly tampered anche se firmato con strong name. La registrazione in GAC richiede lo strong name Se un assembly partially trusted chiama un full trusted con strong name, questo necessita dell'attributo: [assembly:AllowPartiallyTrustedCallers] Delay Signing 1. 2. Task del developer [assembly:AssemblyDelaySign(true)] [assembly:AssemblyKeyFile("PublicKey.snk")] Per testare il codice si disabilita la verifica dello sn per quegli assembly. La disabilitazione non modifica la dll ma il registry! HKLM\Software\Microsoft\StrongName\ sn –Vr MyAssembly.dll Verification\<asmName,publicKeyToken> 3. 4. 5. La lista degli assembly disabilitati alla verifica si ottiene con: sn –Vl Task del Per riabilitare gli assembly alla verifica si procede con: developer e tester sn –Vu MyAssembly.dll Il personale autorizzato provvede a firmare in modo definitivo l'assembly con la chiave privata (magari via smart card): sn –R MyAssembly.dll PrivateKey.snk Task critico solo per admins Il bug dello strong name (grazie ad una segnalazione nei ng USA) Modifica con Hex Editor Al momento: Corretto in Win2K3 SP1 Non corretto in XP Il bug dello strong name Uscita call della slide precedente Custom Permission Dovrebbero sempre essere sealed Derivano da CodeAccessPermission se si vuole lo stack walk Si implementano IPermission, ISecurityEncodable se non si desidera lo stack walk Devono avere strong name Devono essere messe in GAC Devono essere Full Trust Devono essere inserite in una o più Policy Assemblies dei PC dove gira l'assembly Tool: Exporting and deploying Security Policy Create File.MSI Deploy Domande? Full Trust? ... no, grazie Isolated Storage Nella CAS esiste una Permission ad-hoc per l'Isolated Storage File system virtual e isolato Si possono definire delle "quota" (limitazioni in dimensione) Si può definire uno storage isolato sulla base di: Identità del codice dell'applicazione Identità dell'utente Si gestisce con le classi di un namespace dedicato: System.IO.IsolatedStorage IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly(); Tool Adjusting Security Tool: Evaluating an assembly Tool: Trusting an assembly