Roberto Brunetti

Developing in the cloud

.NET Programming

Problema del giorno: Bug nella Forms Authentication....la verità

Dopo il post di Andrea Saltarello (http://blogs.ugidotnet.org/pape/archive/2004/10/01/3536.aspx) ho fatto qualche prova per capire meglio il problema e trovare una soluzione in attesa di patch. Vi consiglio di leggere prima il post di Andrea.

 

Proviamo a mettere tutti i puntini sulle “i”. Scusate le varie ripetizioni, ma il mio obiettivo è spiegare bene la natura del problema e evitare fraintendimenti.

 

Il problema non riguarda la Forms Authentication, bensì il meccanismo di controllo dei tag location presenti nei vari web.config di applicazioni ASP.NET. Nel caso citato, il problema non si verifica in fase di autenticazione, ma nel controllo delle autorizzazioni di ASP.NET implementato nel modulo UrlAuthorizationModule. Tale problema di verifica durante l’evento AuthorizeRequest in cui il modulo verifica che la risorsa sia accessibile dall’utente (dal Principal in realtà: HttpContext.Current.User) che ha effettuato la richiesta. Se il sito contiene un tag di <authorization> generico nel web.config della root del sito il problema non si verifica in quanto tutto il folder è protetto. Se invece vengono usati (come normalmente succede) i tag location per proteggere una risorsa (o un insieme di risorse in una sottodirectory) il problema si verifica in quanto i controlli vengono effettuati sulle stringhe che rappresentano la risorsa richiesta (%5cPagina.aspx oppure %5cDirectory/Pagina.aspx oppure /Directory%5cPagina.aspx) con l’attributo path del tag location (“Pagina.aspx” oppure “Directory/Pagina.aspx” oppure “Directory/Pagina.aspx). La stringa in questione ovviamente non è identica e quindi è come il tag location non viene preso in considerazione, disabilitando di conseguenza tutte le impostazioni settate.

Ricordo che il tag location può essere utilizzato anche per altri settaggi, non solo per gestire le autorizzazioni alle risorse, quindi in realtà il problema è nella lettura della configurazione rispetto ai tag location e quindi riguarda Authorization (e Authentication se vogliamo) solo indirettamente: questo vuol dire che, restando sempre nell’area security, anche la Windows Authentication presenta questa problema e anche la PassPort Authentication. Il problema è generalizzato a tutti i settaggi del tag location per singola risorsa o directory: direi quindi che è un problema di configuration (cioè di come vengono analizzati i tag location per leggere le configurazioni).

L’errore si verifca se nell’url richiesto sono presenti caratteri diversi rispetto a quanto scritto nel tag location. Ad esempio se il tag location contiene path=”Directory/Pagina.aspx”, tale stringa non matcha le richieste effettuate per “Directory\Pagina.aspx” oppure per “Directory%5cPagina.aspx” e neanche le richieste per “Directory\\Pagina.aspx”. IE 5+ trasforma gli url contenenti “\” in url con “/” quindi parzializza il problema. Non trasforma però “\\” in “//”. Netscape non trasforma.

Quindi non occorre che la risorsa sia in una sottodirectory della root del sito...è sufficiente che si faccia una richista per http://xxx.com%5cPagina.aspx per non far matchare il tag location riferito a Pagina.aspx.

 

Il problema non si presenta se si installa UrlScan in quanto è questo signore che blocca la richiesta “encoded” che quindi non arriva mai a ASP.NET. UrlScan è installabile su IIS5 in Windows 2000 e è nativo in IIS 6 - Windows 2003 (che quindi non presenta di default il problema).

UrlScan è comunque un componente consigliato in una configurazione ottimale.

Quindi il problema è di ASP.NET, non si verifica in IIS 6 perchè le richieste encoded vengono bloccate da IIS e non arrivano a ASP.NET.

Il problema si verifica per lo stesso motivo anche se non si usano tag location, ma un web.config in una sottodirectory. Se arriva una richiesta per %5cDirectory/Pagina.aspx non viene preso in considerazione l’intero web.config della “Directory” in quanto il %5c fa si che non venga trovato nessun web.config in tale directory su disco.

 

Come risolvere il problema attendendo una patch ? Semplice, avendo capito bene che il problema non è di autenticazione o autorizzazione...dobbiamo intervenire sulla Request prima possibile ....la classe HttpApplication di cui la nostra applicazione è una specializzazione espone l’evento BeginRequest (non in AuthenticateRequest o AuthorizeRequest...risolveremo il problema citato durante l’autorizzazione, ma non gli altri problemi su altri settaggi di Location o web.config in sottodirectory), dove potrebbe eseguire un RewritePath trasformando noi il carattere “\” in “/”.

Ecco il codice da piazzare nel Global.asax.

 

HttpContext context = ((HttpApplication)sender).Context;

if (context != null)

{

HttpRequest request = context.Request;

string path = request.Path.ToUpper();

if (path.IndexOf("\\") > -1)

     {

          path = path.Replace("\\", "/");

          context.RewritePath(path);

     }

}

 

In questo modo risolviamo sia il problema “\” che il problema “%5c” che comunque in Request.FilePath è già “\”. La richiesta contiene quindi un url “normale” e quindi l’utilizzo del tag location e di web.config in sottodirectory viene ripristinato.

 

Se non siete sicurissimi del mio replace....sostituite anche il %5c con “/”....

HttpContext context = ((HttpApplication)sender).Context;

if (context != null)

{

HttpRequest request = context.Request;

     string path = request.Path.ToUpper();

     if (path.IndexOf("\\") > -1 || path.IndexOf("%5c") > -1)

     {

          path = path.Replace("\\", "/").Replace("%5C", "/");

          context.RewritePath(path);

     }

}

 

Ovviamente tale codice potrebbe essere esteso a altri caratteri sospetti.

Il mio consiglio: invece di scrivere tale codice nel global.asax di ogni applicazione, conviene scriversi un modulo http che si lega all’evento BeginRequest. Il modulo potrà essere utilizzato in tutte le applicazioni e soprattutto rimosso il giorno che uscirà una patch SENZA DOVER RICOMPILARE TUTTI I PROGETTI.

 

Per fare un modulo Http è sufficiente creare una classe che implementa IhttpModule.

public class Proteggimi : IHttpModule {
    public Proteggimi() {}

    public void Init(HttpApplication context) {
        context.BeginRequest +=new EventHandler(context_BeginRequest);
    }

    public void Dispose() {}

    private void context_BeginRequest(object sender, EventArgs e)
    {
       
HttpApplication context = sender as HttpApplication;

        if (context != null) {

            HttpRequest request = context.Request;

            string path = request.Path.ToUpper();

            if (path.IndexOf("\\") > -1 || path.IndexOf("%5C") > -1) {

                path = path.Replace("\\", "/").Replace("%5C", "/");

                context.Context.RewritePath(path);

            }

        }

    }

}

Se il modulo lavora in una sola applicazione si può mettere il CS nel progetto di VS.NET compilando tutto insieme e aggiungendo nel web.config della root.

<httpModules>

<add name="Proteggimi" type="NamespaceDelProgetto.Proteggimi, Proteggimi" />

</httpModules>

 

Ovviamente NameSpaceDelProgetto deve essere sostutuito con il “vostro” Namespace.

Se invece il tutto deve essere portato in varie applicazioni o create una dll privata che copiate in tutte le bin delle varie applicazioni (sempre mettendo httpModules nel web.config), oppure create un assembly pubblico, lo inserite nella GAC e nel web.config dovrete usare lo strong name.

 

Spero di aver chiarito il tutto.

Alla prossima.

 

RoB

 

 

Posted: ott 02 2004, 12.09 by rob | with 15 comment(s)
Filed under:

Comments

TrackBack said:

# ottobre 2, 2004 1.56

TrackBack said:

# ottobre 2, 2004 4.11

TrackBack said:

# ottobre 2, 2004 4.13

TrackBack said:

# ottobre 2, 2004 10.51

TrackBack said:

# ottobre 3, 2004 10.55

TrackBack said:

# ottobre 4, 2004 9.37

TrackBack said:

# ottobre 6, 2004 9.26

TrackBack said:

# ottobre 6, 2004 10.16

TrackBack said:

# ottobre 7, 2004 12.07

TrackBack said:

# ottobre 7, 2004 1.21

TrackBack said:

# ottobre 7, 2004 1.24

TrackBack said:

# ottobre 7, 2004 1.25

TrackBack said:

# ottobre 7, 2004 1.55

TrackBack said:

# ottobre 8, 2004 10.27

viagra said:

qi bu

# agosto 17, 2007 11.28