La sicurezza di ASP.NET e IIS Raffaele Rialdi Microsoft C# MVP MVP Profile Blog.
-
Upload
gianpiero-campana -
Category
Documents
-
view
221 -
download
4
Transcript of La sicurezza di ASP.NET e IIS Raffaele Rialdi Microsoft C# MVP MVP Profile Blog.
La sicurezza di ASP.NET e IISLa sicurezza di ASP.NET e IIS
Raffaele RialdiRaffaele RialdiMicrosoft C# MVPMicrosoft C# MVP http://mvp.support.microsoft.comhttp://mvp.support.microsoft.comMVP ProfileMVP Profile http://snipurl.com/f0cvhttp://snipurl.com/f0cvBlogBlog http://blogs/ugidotnet.org/raffaelehttp://blogs/ugidotnet.org/raffaele
[email protected]@vevy.comVevy Europe SpAVevy Europe SpA
AgendaAgenda
IIS
Asp.net.aspx, .asmx, .asax, .ascx, .soap, .rem, ...
NTFS LDAP SQL
Web Application
• Anonymous• Basic• Windows• Certificate
• None• Windows• Forms• Passport
• Imperative• Declarative
Spying
Spoofing / Tampering
Sql/script Injection
D.O.S.
Autenticazione("chi sei?")
Autorizzazione("cosa posso fare?")
• UrlAuthorizationModule• FileAuthorizationModule
• NTFS Access Control List (ACL)
Meccanismi diMeccanismi diAutenticazioneAutenticazione
IISIIS AnonimaAnonima
BasicBasic
DigestDigest
CertificateCertificate
WindowsWindows
Asp.netAsp.net PassportPassport
FormsForms
IIS mappa l'utente su IUSR_nomemacchinaIIS mappa l'utente su IUSR_nomemacchina Asp.net lo vede come ""Asp.net lo vede come "" Utente non viene riconosciuto anche se è in Utente non viene riconosciuto anche se è in
LanLan Usano lo store delle credenziali di WindowsUsano lo store delle credenziali di Windows Richiedono una CAL per ogni utenteRichiedono una CAL per ogni utente
Credenziali in chiaro (necessita SSL)Credenziali in chiaro (necessita SSL)
La password non viaggia sulla reteLa password non viaggia sulla rete
Differenze architetturali Differenze architetturali tra IIS5 e IIS6tra IIS5 e IIS6
inetinfo (IIS)account: localsystem
workerprocess(w3wp)
appdomain
appdomain
Una web application
per appdomain
App Pool 1
inetinfo (IIS)account: localsystem
workerprocess
(aspnet_wp)
appdomain
appdomain
aspnet (default)Configurabile nel machine.config
workerprocess(w3wp)
appdomain
appdomain
workerprocess(w3wp)
appdomain
appdomain
App Pool 2 App Pool 3
appdomain
Un account per App Pool.(token di processo)
Devono essere membri del gruppo IIS_WPG
Configurabile da IIS
Network_service(default) User1 User2
IIS 5 IIS 6
HTTP.SYS (Kernel Mode)
Windows AuthenticationWindows Authenticationstep-by-stepstep-by-step
1.1. Web.config di default è pronto:Web.config di default è pronto:
2.2. Impostare le autorizzazioniImpostare le autorizzazioni
3.3. Disabilitare l'autenticazione anonima in IIS ... Disabilitare l'autenticazione anonima in IIS ... (prossime slide)(prossime slide)
4.4. L'utente autenticato è: L'utente autenticato è: (stringa vuota se anonimo)(stringa vuota se anonimo)
5.5. L'utente usato dal worker process è:L'utente usato dal worker process è:
<authentication mode="Windows" /><authentication mode="Windows" />
<authorization><deny users="?" /><allow users="*" />
</authorization>
<authorization><deny users="?" /><allow users="*" />
</authorization>
?? utente anonimo utente anonimo
** tutti gli utenti tutti gli utenti
?? utente anonimo utente anonimo
** tutti gli utenti tutti gli utenti
System.Security.Principal.WindowsIdentity.GetCurrent().NameSystem.Security.Principal.WindowsIdentity.GetCurrent().Name
HttpContext.Current.User.Identity.NameHttpContext.Current.User.Identity.Name
Internet Information ServerInternet Information ServerIIS5 (Windows 2000 / XP Pro)IIS5 (Windows 2000 / XP Pro)
Internet Information ServerInternet Information ServerIIS6 (Windows 2003)IIS6 (Windows 2003)
IIS6 Application poolIIS6 Application pool
ImpersonationImpersonation(solo con Windows Authentication)(solo con Windows Authentication)
Il token di security dell'utente autenticato viene Il token di security dell'utente autenticato viene impostato sul thread.impostato sul thread.Il token di processo rimane invariato.Il token di processo rimane invariato.
Se l'utente è anonimo, viene impersonato Se l'utente è anonimo, viene impersonato IUSR_IUSR_NomePcNomePc
Sintassi (web.config): <identity impersonate=true />Sintassi (web.config): <identity impersonate=true />
IIS5 non può eseguire più worker process sotto IIS5 non può eseguire più worker process sotto identità diverseidentità diverseSoluzione: impersonation di un utente specificoSoluzione: impersonation di un utente specifico<identity impersonate=true user="xxx" <identity impersonate=true user="xxx" password="zzz" />password="zzz" />
I problemi I problemi architetturaliarchitetturali di Impersonationdi Impersonation
Molti vogliono usare la security di Sql serverMolti vogliono usare la security di Sql server
Se il db è in rete, impersonation non funziona ma ci Se il db è in rete, impersonation non funziona ma ci vuole invece delegationvuole invece delegation
Si perde il controllo centralizzato della securitySi perde il controllo centralizzato della security(accedere a Ntfs, Ldap, risorse in rete, DB)(accedere a Ntfs, Ldap, risorse in rete, DB)
La security 'per righe' fatta con sql server è un incuboLa security 'per righe' fatta con sql server è un incubo
I problemi I problemi tecnologicitecnologici di Impersonationdi Impersonation Il token dell'utente non può essere usato per accedere Il token dell'utente non può essere usato per accedere
a risorse remote (per es. la webapp non può usarlo per a risorse remote (per es. la webapp non può usarlo per accedere un db in rete)accedere un db in rete)La soluzione viene con Delegation che è di default La soluzione viene con Delegation che è di default disabilitata (proprio perchè è pericolosa!)disabilitata (proprio perchè è pericolosa!)
Impersonation implica contesti diversi per ciascun Impersonation implica contesti diversi per ciascun utente. Questo significa niente connection poolingutente. Questo significa niente connection pooling
Protezione limitata. Un eventuale buffer overrun può Protezione limitata. Un eventuale buffer overrun può usare sia il token di thread (impersonato) che quello di usare sia il token di thread (impersonato) che quello di processo (worker process) usando RevertToSelf.processo (worker process) usando RevertToSelf.
Se chiamo un componente COM che sta in un Se chiamo un componente COM che sta in un apartment diverso, COM non userà il token di apartment diverso, COM non userà il token di impersonazione ma quello di processoimpersonazione ma quello di processo
Scenario tipico di una webappScenario tipico di una webapp
Browser Firewall Web Server Data Server
worker process
token di processo = aspnettoken di thread (solo se usa impersonation)
Alice aspnet
Anche abilitando impersonationil Data Server verrà accesso come aspnet
Forms AuthenticationForms Authenticationstep-by-stepstep-by-step1.1. Abilitare l'autenticazione anonima in IISAbilitare l'autenticazione anonima in IIS
2.2. Impostare l'autenticazione e i suoi parametriImpostare l'autenticazione e i suoi parametri
3.3. Impostare le autorizzazioniImpostare le autorizzazioni
4.4. Creare la pagina di login controllare l'utente e autorizzarloCreare la pagina di login controllare l'utente e autorizzarlo
<authentication mode="Forms"><forms name="myCookieName" loginUrl="~/Login.aspx" />
</authentication>
<authentication mode="Forms"><forms name="myCookieName" loginUrl="~/Login.aspx" />
</authentication>
<authorization><deny users="?" /><allow users="*" />
</authorization>
<authorization><deny users="?" /><allow users="*" />
</authorization>
if(UserDB.Check(txtUsername.Text, txtPassword.Text)){
FormsAuthentication.RedirectFromLoginPage(txtUsername.Text, ckRemember.Checked);
}
if(UserDB.Check(txtUsername.Text, txtPassword.Text)){
FormsAuthentication.RedirectFromLoginPage(txtUsername.Text, ckRemember.Checked);
}
?? utente anonimo utente anonimo
** tutti gli utenti tutti gli utenti
?? utente anonimo utente anonimo
** tutti gli utenti tutti gli utenti
Forms AuthenticationForms Authenticationgestire i ruoligestire i ruoli
1.1. Gestire l'evento Application_AuthenticateRequestGestire l'evento Application_AuthenticateRequest
2.2. Impostare le autorizzazioni per singole parti del sitoImpostare le autorizzazioni per singole parti del sito
protected void Application_AuthenticateRequest(Object sender, EventArgs e){
UserDB.AssignRoles();}
protected void Application_AuthenticateRequest(Object sender, EventArgs e){
UserDB.AssignRoles();}
<location path="Backoffice.aspx"><system.web>
<authorization><deny users="?" /><allow roles="admins" /><deny users="*" />
</authorization></system.web>
</location>
<location path="Backoffice.aspx"><system.web>
<authorization><deny users="?" /><allow roles="admins" /><deny users="*" />
</authorization></system.web>
</location>
L'ordine di valutazione L'ordine di valutazione delle autorizzazioni è delle autorizzazioni è dal primo verso l'ultimo.dal primo verso l'ultimo.
Il primo 'match' vince.Il primo 'match' vince.
L'ordine di valutazione L'ordine di valutazione delle autorizzazioni è delle autorizzazioni è dal primo verso l'ultimo.dal primo verso l'ultimo.
Il primo 'match' vince.Il primo 'match' vince.
Forms AuthenticationForms AuthenticationGestione utenti e ruoliGestione utenti e ruoli Si costruisce una piccola classe:Si costruisce una piccola classe:
public class UserDB{
public static bool CheckUser(string Username, string Password){
return (Username == Password);// Solo per la demo!!! ;-)}
public static void AssignRoles(){
IPrincipal CurrentUser = HttpContext.Current.User;if(CurrentUser != null && CurrentUser.Identity.IsAuthenticated &&
CurrentUser.Identity.AuthenticationType == "Forms"){
string User = CurrentUser.Identity.Name;string [] roles = GetRolesForUser(User);CurrentUser = new System.Security.Principal.GenericPrincipal
(CurrentUser.Identity, roles);}
}
private static string[] GetRolesForUser(string User){
string[] roles = new string[2];roles[0] = "Administrators";roles[1] = "Users";return roles; // Solo per la demo!
}}
public class UserDB{
public static bool CheckUser(string Username, string Password){
return (Username == Password);// Solo per la demo!!! ;-)}
public static void AssignRoles(){
IPrincipal CurrentUser = HttpContext.Current.User;if(CurrentUser != null && CurrentUser.Identity.IsAuthenticated &&
CurrentUser.Identity.AuthenticationType == "Forms"){
string User = CurrentUser.Identity.Name;string [] roles = GetRolesForUser(User);CurrentUser = new System.Security.Principal.GenericPrincipal
(CurrentUser.Identity, roles);}
}
private static string[] GetRolesForUser(string User){
string[] roles = new string[2];roles[0] = "Administrators";roles[1] = "Users";return roles; // Solo per la demo!
}}
Principal e IdentityPrincipal e IdentityLa sicurezza basata sui ruoli secondo il La sicurezza basata sui ruoli secondo il frameworkframework
IIdentity rappresenta l'identità di un utenteIIdentity rappresenta l'identità di un utenteWindowsIdentity, FormsIdentity, PassportIdentity, GenericIdentityWindowsIdentity, FormsIdentity, PassportIdentity, GenericIdentity
IPrincipal contiene l'Identity e i ruoliIPrincipal contiene l'Identity e i ruoliWindowsPrincipal, GenericPrincipalWindowsPrincipal, GenericPrincipal
AuthenticationTypeAuthenticationType
IsAuthenticatedIsAuthenticated
NameName
String. "Windows", "Forms", "Passport", ...String. "Windows", "Forms", "Passport", ...
Bool. Indica se l'utente è autenticatoBool. Indica se l'utente è autenticato
String. Nome dell'utenteString. Nome dell'utente
String. "Windows", "Forms", "Passport", ...String. "Windows", "Forms", "Passport", ...
Bool. Indica se l'utente è autenticatoBool. Indica se l'utente è autenticato
String. Nome dell'utenteString. Nome dell'utente
IdentityIdentity
IsInRoleIsInRole
IIdentity.IIdentity.
Bool. Indica se l'utente appartiene ad un certo ruolo (gruppo)Bool. Indica se l'utente appartiene ad un certo ruolo (gruppo)
IIdentity.IIdentity.
Bool. Indica se l'utente appartiene ad un certo ruolo (gruppo)Bool. Indica se l'utente appartiene ad un certo ruolo (gruppo)
Forms AuthenticationForms AuthenticationGestione utentiGestione utenti
Gli utenti si possono anche gestire nel web.config ma è Gli utenti si possono anche gestire nel web.config ma è sconsigliato:sconsigliato:
<authentication mode="Forms"><forms name="myCookieName" loginUrl="~/Login.aspx">
<credentials passwordFormat = "SHA1" <user name="UserName1" password="SHA1EncryptedPassword1"/>
</credentials></forms>
</authentication>
<authentication mode="Forms"><forms name="myCookieName" loginUrl="~/Login.aspx">
<credentials passwordFormat = "SHA1" <user name="UserName1" password="SHA1EncryptedPassword1"/>
</credentials></forms>
</authentication>
Esempio Forms AuthenticationEsempio Forms AuthenticationEsempio Forms AuthenticationEsempio Forms Authentication
Forms Authentication TipForms Authentication Tip
Diciamo di avere due Web Application ...Diciamo di avere due Web Application ...
Prendiamo in considerazione:Prendiamo in considerazione:
1.1. Nome del cookieNome del cookie della Forms authentication della Forms authentication
2.2. Path del cookiePath del cookie
3.3. Il tag Il tag <machineKey ... /><machineKey ... /> nel web.config nel web.config(vedi http://support.microsoft.com?id=312906)(vedi http://support.microsoft.com?id=312906)
Se sonoSe sono identici identici, l'utente potrà navigare da una all'altra , l'utente potrà navigare da una all'altra senza doversi ri-autenticaresenza doversi ri-autenticare
Se almeno Se almeno uno di questi è diversouno di questi è diverso, sarà necessario , sarà necessario ri-autenticarsiri-autenticarsi
Autenticazione mistaAutenticazione mistaWindows / FormsWindows / Forms
Il problema:Il problema:
In Windows Authentication, l'header HTTP In Windows Authentication, l'header HTTP "LOGON_USER" contiene il nome utente"LOGON_USER" contiene il nome utente
Se IIS è configurato come anonimo, NON viene Se IIS è configurato come anonimo, NON viene passato il nome utente anche se siamo loggati passato il nome utente anche se siamo loggati sul dominiosul dominio
... Ma la Forms authentication richiede che IIS ... Ma la Forms authentication richiede che IIS sia configurato come anonimosia configurato come anonimo(altrimenti compare la dialog di autenticazione)(altrimenti compare la dialog di autenticazione)
Autenticazione mistaAutenticazione mistaWindows / FormsWindows / Forms
La soluzione:La soluzione:
Due pagine di Login: Forms e WindowsDue pagine di Login: Forms e Windows
Web.config configurato per la FormsWeb.config configurato per la Forms
Autorizzazione a tutti per Autorizzazione a tutti per la pagina di Login Windowsla pagina di Login Windows
IIS – WebApp: abilitare accesso anonimoIIS – WebApp: abilitare accesso anonimo
IIS – LoginWin.aspx: togliere accesso anonimoIIS – LoginWin.aspx: togliere accesso anonimo
LoginWin.aspx: Crea il ticket della Forms authenticaion LoginWin.aspx: Crea il ticket della Forms authenticaion a partire dalle credenziali Windowsa partire dalle credenziali Windows
<location path="LoginWin.aspx"><system.web>
<authorization><allow users="*" />
</authorization></system.web>
</location>
<location path="LoginWin.aspx"><system.web>
<authorization><allow users="*" />
</authorization></system.web>
</location>
Esempio autenticazione mistaEsempio autenticazione mistaEsempio autenticazione mistaEsempio autenticazione mista
Forms AuthenticationForms Authenticationcon LDAPcon LDAP
LDAP è un protocollo per dialogare con Active DirectoryLDAP è un protocollo per dialogare con Active Directory
Posso chiedere con LDAP:Posso chiedere con LDAP:
di verificare le credenziali di un utente su ADdi verificare le credenziali di un utente su AD
di darmi l'elenco dei gruppi a cui appartiene quell'utentedi darmi l'elenco dei gruppi a cui appartiene quell'utente
Il codice per fare queste due cose è qui:Il codice per fare queste due cose è qui:http://support.microsoft.com/?id=326340http://support.microsoft.com/?id=326340
Metodo 1: Metodo 1: Public Function IsAuthenticated(ByVal domain As String, Public Function IsAuthenticated(ByVal domain As String, ByVal username As String, ByVal pwd As String) As BooleanByVal username As String, ByVal pwd As String) As Boolean
Metodo 2: Public Function GetGroups() As StringMetodo 2: Public Function GetGroups() As String
Un ottimo motivo per usarla è nelle WebApp con Un ottimo motivo per usarla è nelle WebApp con autenticazione mista Windows + Formsautenticazione mista Windows + Forms
Dove siamo?Dove siamo?
Autenticazione
Autorizzazione
ControlloImperativo
Controllodichiarativo
RaffaeleRaffaeleRaffaeleRaffaeleIISBasic, Win, ...
Asp.netPassport, Form
IISNTFS
Asp.net<authorization ... />
Pagina si/noPagina si/noPagina si/noPagina si/no
Asp.netPrincipalPermission, etc.
Codice si/noCodice si/noCodice si/noCodice si/no
SicurezzaSicurezzaimperativa e dichiarativaimperativa e dichiarativa
Gli attrezzi del mestiere:Gli attrezzi del mestiere: IPrincipal.IsInRole()IPrincipal.IsInRole() Imperativa (bool) Imperativa (bool)
PrincipalPermission.Demand()PrincipalPermission.Demand() Imperativa Imperativa (SecurityException)(SecurityException)
PrincipalPermissionAttributePrincipalPermissionAttribute Dichiarativa Dichiarativa (SecurityException)(SecurityException)
if(User.IsInRole("Admins")) { ... }if(User.IsInRole("Admins")) { ... }
PrincipalPermission perm = new PrincipalPermission(null, "Admins");perm.Demand();
PrincipalPermission perm = new PrincipalPermission(null, "Admins");perm.Demand();
PrincipalPermissionAttribute
[PrincipalPermission(SecurityAction.Demand, Role="Admins")]public void MyAdminMethod() {...}
PrincipalPermissionAttribute
[PrincipalPermission(SecurityAction.Demand, Role="Admins")]public void MyAdminMethod() {...}
Esempio SecureHandlerEsempio SecureHandlerRole Based AuthorizationRole Based AuthorizationEsempio SecureHandlerEsempio SecureHandlerRole Based AuthorizationRole Based Authorization
Mai dare informazioni prezioseMai dare informazioni preziosedefault: <customErrors mode="RemoteOnly" /> default: <customErrors mode="RemoteOnly" />
Qualsiasi informazione sugli errori può essere sfruttata Qualsiasi informazione sugli errori può essere sfruttata da un hacker.da un hacker.
Gli errori custom (che nascondono i dettagliati):Gli errori custom (che nascondono i dettagliati): mode="Off" mode="Off" mostrati a nessuno mostrati a nessuno mode="On" mode="On" mostrati a tutti mostrati a tutti mode="RemoteOnly" mode="RemoteOnly" solo in remoto solo in remoto
Questo meccanismo è poco elasticoQuesto meccanismo è poco elastico Possiamo usare un HttpModule per migliorare la Possiamo usare un HttpModule per migliorare la
situazione ....situazione ....
CustomErrorHandlerCustomErrorHandler(esempio)(esempio)
1.1. Web.Config:Web.Config:
<customErrors mode="On" defaultRedirect="~/HttpErrors.aspx" /><customErrors mode="On" defaultRedirect="~/HttpErrors.aspx" />
.... ....
<httpModules><httpModules>
<add type="CustomErrorHandler.RafErrorModule,<add type="CustomErrorHandler.RafErrorModule,
CustomErrorHandler" name="RafErrorModule"/>CustomErrorHandler" name="RafErrorModule"/>
</httpModules> </httpModules>
2.2. Due pagine di gestione errore:Due pagine di gestione errore:
SoftError.aspx (per utenti) e HardError.aspx (per admin)SoftError.aspx (per utenti) e HardError.aspx (per admin)
3.3. Il Module redirige gli errori Il Module redirige gli errori a seconda del ruoloa seconda del ruolo dell'utente dell'utente
4.4. Il Module gestisce Il Module gestisce gli errori Httpgli errori Http e e le Exceptionle Exception
... vediamo il codice ...... vediamo il codice ...
Esempio CustomErrorHandlerEsempio CustomErrorHandlerEsempio CustomErrorHandlerEsempio CustomErrorHandler
HttpRequestValidationExceptionHttpRequestValidationException<%@ Page validateRequest="true" %><%@ Page validateRequest="true" %>(true by default)(true by default)
Riconosce un eventuale Riconosce un eventuale input maliziosoinput malizioso dell'utente e lancia l'eccezione dell'utente e lancia l'eccezione HttpRequestValidationExceptionHttpRequestValidationException
Se però voglio accettare una Se però voglio accettare una stringa html/scriptstringa html/script dall'utente? dall'utente?
Opzione 1: validateRequest = Opzione 1: validateRequest = falsefalse (vale per tutta la pagina) e (vale per tutta la pagina) e validarla.validarla. Opzione 2: criptare sul client, decrittarla sul server e Opzione 2: criptare sul client, decrittarla sul server e validarlavalidarla..
1.1. Sul client (durante la onsubmit) si cripta il contenuto con Sul client (durante la onsubmit) si cripta il contenuto con encodeencode di di javascriptjavascript
2.2. il contenuto criptato si mette dentro un <input type=hidden>il contenuto criptato si mette dentro un <input type=hidden>
3.3. sul server si usa sul server si usa HttpUtility.UrlDecodeHttpUtility.UrlDecode per decodificare la stringa per decodificare la stringa
La validazione ...La validazione ... si può usare Server.HtmlEncode per farlo apparire sulla paginasi può usare Server.HtmlEncode per farlo apparire sulla pagina si può fare il parsing per eliminare i tag pericolosisi può fare il parsing per eliminare i tag pericolosi
<Input type=hidden /><Input type=hidden /> Spesso viene usato un campo hidden per conservare i Spesso viene usato un campo hidden per conservare i
dati tra un postback e l'altrodati tra un postback e l'altro
La modifica (tampering) dei campi hidden è banale e, La modifica (tampering) dei campi hidden è banale e, se non controllata adeguatamente, può comportare un se non controllata adeguatamente, può comportare un duro attacco.duro attacco.
Soluzione:Soluzione: Criptarli prima di mandarli al clientCriptarli prima di mandarli al client Decrittarli dentro un try/catch quando tornano al serverDecrittarli dentro un try/catch quando tornano al server
Protezione del ViewstateProtezione del Viewstate
Il Viewstate di default è un campo <input type=hidden />Il Viewstate di default è un campo <input type=hidden /> Il Viewstate contiene lo stato dei controlli sul lato serverIl Viewstate contiene lo stato dei controlli sul lato server Se non è criptato, è facilmente visibile:Se non è criptato, è facilmente visibile:
http://www.pluralsight.com/toolcontent/ViewStateDecoder11.ziphttp://www.pluralsight.com/toolcontent/ViewStateDecoder11.zip
Soluzioni:Soluzioni:
1.1. Criptarlo: <%@ Page enableViewStateMac=“true” />Criptarlo: <%@ Page enableViewStateMac=“true” />Mac = machine authentication check Mac = machine authentication check La chiave e il metodo di encryption sono specificati nel tag La chiave e il metodo di encryption sono specificati nel tag
<machineKey> del machine.config (autogenerazione)<machineKey> del machine.config (autogenerazione) Per crearne e specificarne di nuovi nel web.config: Q312906Per crearne e specificarne di nuovi nel web.config: Q312906
2.2. Salvarlo sul server:Salvarlo sul server:http://www.aspalliance.com/articleViewer.aspx?aId=72&vId=&pId=http://www.aspalliance.com/articleViewer.aspx?aId=72&vId=&pId=http://msdn.microsoft.com/msdnmag/issues/03/02/CuttingEdge/default.aspxhttp://msdn.microsoft.com/msdnmag/issues/03/02/CuttingEdge/default.aspx
Proteggere le risorseProteggere le risorse Molti file non devono poter essere scaricati via http Molti file non devono poter essere scaricati via http
dall'utentedall'utente Nel machine.config Asp.net protegge di default alcuni Nel machine.config Asp.net protegge di default alcuni
tipi di file dal download (.cs, .config, ...)tipi di file dal download (.cs, .config, ...)
Soluzione 1: custodirlo fuori dalla cartella virtualeSoluzione 1: custodirlo fuori dalla cartella virtuale Soluzione 2: proteggere il file via NTFS (se si usa Soluzione 2: proteggere il file via NTFS (se si usa
impersonation.)impersonation.) Soluzione 3: proteggere con asp.netSoluzione 3: proteggere con asp.net
Associare i file da proteggere in IIS all'Isapi di Asp.netAssociare i file da proteggere in IIS all'Isapi di Asp.net Proteggere (ad esempio) i file mdb nel web.config:Proteggere (ad esempio) i file mdb nel web.config:
<httpHandlers><httpHandlers><add<add verb="*" path="*.mdb"verb="*" path="*.mdb"
type="type="System.Web.HttpForbiddenHandlerSystem.Web.HttpForbiddenHandler" />" /></httpHandlers></httpHandlers>
CAS e ASP.netCAS e ASP.net
Livello di Trust Restrizioni della CAS
Full • Nessuna restrizione sulle permission.
• Applicazioni possono accedere a risorse controllate dalle impostazioni del sistema operativo
• Possono essere fatte operazioni che richiedono un alto privilegio
High • Non si può chiamare codice nativo
• Non si possono usare serviced components
• Non si può scrivere nell'event log
• Non si può accedere alle code di msmq
• Non si può usare data source di tipo OLE DB
Medium • L'accesso ai file è ristretto alla cartella dell'applicazione
• Non si può accedere al registry
Low • Non si può accedere a SQL Server
• Non si può chiamare CodeAccessPermission.Assert
Minimal • Si ha solo il diritto di esecuzione e nulla di più
Q & AQ & A
........
© 2003-2004 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
SQL InjectionSQL Injection Un pirata può devastare il db ...Un pirata può devastare il db ...
Select * from authors where au_lname like ' Select * from authors where au_lname like ' ' ; drop authors - - ' ; drop authors - - ' 'Select * from authors where au_lname like ' Select * from authors where au_lname like ' ' ; drop authors - - ' ; drop authors - - ' '
string strSql = "Select * from authors where au_lname like '" + TextBox1.Text + "'";
SqlCommand cmd = new SqlCommand(strSql, Cnn);SqlDataReader dr = cmd.ExecuteReader();
string strSql = "Select * from authors where au_lname like '" + TextBox1.Text + "'";
SqlCommand cmd = new SqlCommand(strSql, Cnn);SqlDataReader dr = cmd.ExecuteReader();
Prima queryPrima queryPrima queryPrima query Seconda querySeconda querySeconda querySeconda query
ScartatoScartatoScartatoScartato
SQL InjectionSQL Injection... usare i parameters!!! ...... usare i parameters!!! ... I Parameters incrementano anche le performance:I Parameters incrementano anche le performance:
non c'è conversione da string a tipo sul dbnon c'è conversione da string a tipo sul db la query rimane compilata e preparata sul db serverla query rimane compilata e preparata sul db server
exec sp_executesql N'Select * from authors exec sp_executesql N'Select * from authors
where au_lname like @au_lname', where au_lname like @au_lname',
N'@au_lname varchar(40)', @au_lname =N'@au_lname varchar(40)', @au_lname = '' '' ' ; drop authors - - ' ' ; drop authors - - '
exec sp_executesql N'Select * from authors exec sp_executesql N'Select * from authors
where au_lname like @au_lname', where au_lname like @au_lname',
N'@au_lname varchar(40)', @au_lname =N'@au_lname varchar(40)', @au_lname = '' '' ' ; drop authors - - ' ' ; drop authors - - '
apice raddoppiato da ADO.NETapice raddoppiato da ADO.NETapice raddoppiato da ADO.NETapice raddoppiato da ADO.NET
Gli apici non sono l'unico problema:Gli apici non sono l'unico problema:select * from titles where royalty = select * from titles where royalty = 0 ; drop authors0 ; drop authorsGli apici non sono l'unico problema:Gli apici non sono l'unico problema:select * from titles where royalty = select * from titles where royalty = 0 ; drop authors0 ; drop authors
string strSql = "Select * from authors where au_lname like @au_lname";
SqlCommand cmd = new SqlCommand(strSql, Cnn);cmd.Parameters.Add("@au_lname", SqlDbType.VarChar,40);SqlDataReader dr = cmd.ExecuteReader();
string strSql = "Select * from authors where au_lname like @au_lname";
SqlCommand cmd = new SqlCommand(strSql, Cnn);cmd.Parameters.Add("@au_lname", SqlDbType.VarChar,40);SqlDataReader dr = cmd.ExecuteReader();
XSS: Cross Site ScriptingXSS: Cross Site Scripting
From: HackerTo: RaffaeleSubject: Free gift
Click here to win
From: HackerTo: RaffaeleSubject: Free gift
Click here to win
1.1. Normale navigazioneNormale navigazione2.2. Email con link contenente un attacco XSSEmail con link contenente un attacco XSS3.3. Il link effetua una GET sul sito della banca con la Il link effetua una GET sul sito della banca con la
QueryString QueryString 4.4. La banca (non protetta da XSS) restituisce nella pagina La banca (non protetta da XSS) restituisce nella pagina
html lo script inviatohtml lo script inviato5.5. Lo script viene eseguito dal browser e le informazioni Lo script viene eseguito dal browser e le informazioni
riservate arrivano al piratariservate arrivano al pirata
Mappare una estensione in IISMappare una estensione in IIS
Affinchè asp.net (e quindi handlers e moduli) abbiano il Affinchè asp.net (e quindi handlers e moduli) abbiano il controllo di un tipo di file (.jpg nell'esempio) è necessario controllo di un tipo di file (.jpg nell'esempio) è necessario configurare IISconfigurare IIS
slide post-sessione
Path dell'isapi di asp.net Path dell'isapi di asp.net (copiarla da quella di .aspx)(copiarla da quella di .aspx)Path dell'isapi di asp.net Path dell'isapi di asp.net (copiarla da quella di .aspx)(copiarla da quella di .aspx)
PromemoriaPromemoria
Installate XP SP2 e Win2K3 SP1!Installate XP SP2 e Win2K3 SP1! Aggiornare Aggiornare sempresempre con Windows Update con Windows Update Proteggere i dati sensibiliProteggere i dati sensibili
DPAPI per criptare (vedi Pattern & Practices sul sito MSDN)DPAPI per criptare (vedi Pattern & Practices sul sito MSDN) ASPnet_setreg.exe per salvare credenziali criptate nel registry ASPnet_setreg.exe per salvare credenziali criptate nel registry
(per esempio di sql). Vedi Q329290 per i dettagli.(per esempio di sql). Vedi Q329290 per i dettagli. Eseguire logging e auditingEseguire logging e auditing Usare UrlScan. Usare UrlScan. UrlScan Monitor (Lorenzo Barbieri) UrlScan Monitor (Lorenzo Barbieri)
http://www.gotdotnet.com/Community/Workspaces/workspace.aspx?http://www.gotdotnet.com/Community/Workspaces/workspace.aspx?id=c859a9fd-3cfd-4d2d-bbe9-4bcc334ed2c3id=c859a9fd-3cfd-4d2d-bbe9-4bcc334ed2c3
IIS LockDown (solo IIS5)IIS LockDown (solo IIS5) Secure Configuration Wizard (solo IIS6 Secure Configuration Wizard (solo IIS6 W2K3 SP1) W2K3 SP1)
slide post-sessione