ModSecurity: CRS 20, protocol violations, Regola 960911 | OTHER chapters | |||
Lo scopo di questo secondo file di configurazione di ModSecurity è di creare eventuali eccezioni per i programmi che, a volte inavvertitamente, inviano richieste non conformi al protocollo HTTP. Questa non conformità, infatti, non sempre indica attività illecite.
Questa prima direttiva è una direttiva
Se l'operatore OPERATOR dovesse riscontrare, all'interno della variabile o delle variabili VARIABLES, una determinata condizione, espressa dall'operatore stesso, allora ModSecurity eseguirebbe le azioni previste in ACTIONS. Nel nostro caso, la variabile da analizzare è REQUEST_LINE, che contiene la prima riga della richiesta HTTP. La REQUEST_LINE, nel protocollo HTTP, contiene: il metodo HTTP da utilizzare ( GET, POST, HEAD, PUT, DELETE, CONNECT, OPTIONS, TRACE ), l'indirizzo ( assoluto o relativo ) della risorsa richiesta ( per esempio, il file
Lo scopo di questa direttiva, quindi, è verificare la conformità di una REQUEST_LINE agli standard ( RCF 2616 ). Per quanto riguarda l'operatore da utilizzare, in questa regola sembra non essere citato. Quando ModSecurity non trova l'operatore da utilizzare, utilizza l'operatore di default: il motore delle espressioni regolari ( REGEX o REGular EXpressions ). Infatti, tutta l'espressione compresa tra le virgolette di apertura e chiusura altro non è che una espressione regolare. La libreria utilizzata da ModSecurity per le espressioni regolari è la libreria PCRE ( Perl-Compatible Regular Expressions ). Questa espressione regolare contiene esattamente la stringa di testo che stiamo cercando nella variabile REQUEST_LINE. La prima osservazione che possiamo fare sul pattern REGEX è che, come nell'esempio visto nel primo articolo, il pattern esprime l'intera stringa di riferimento ( REQUEST_LINE ), visto che è compreso tra gli operatori:
che indicano, rispettivamente, l'inizio della stringa di riferimento (
che dice al motore REGEX: trovami questo subpattern, ma non memorizzarlo. Il subpattern principale, che, a sua volta, ne annida altri, è il subpattern che abbraccia l'intero pattern. Il primo subpattern annidato, invece, è quello che abbraccia la gran parte dell'intero pattern:
La prima osservazione da evidenziare è che questo primo subpattern annidato contiene, al suo interno, ben due operatori OR (
oppure (
oppure (
La seconda ed la terza alternativa sono le più intuitive. La seguente REQUEST_LINE:
invia al server remoto la richiesta di spedire al server richiedente non una risorsa ( un file, il risultato di un programma ), bensì l'elenco delle opzioni accettate, se non addirittura pretese obbligatoriamente, dal server remoto stesso, nel corso di una transazione HTTP. Questa stringa di testo corrisponde esattamente alla nostra terza alternativa ( esclusa, naturalmente, la parte finale, che dobbiamo ancora riscontrare ):
dove l'asterisco
Questa è la REQUEST_LINE di una richiesta HTTP inviata da un client ad un server proxy, al fine di creare un canale di comunicazione protetto ( tunnel ), tra il client ed il server di destinazione, prima di avviare, con quest'ultimo, una transazione protetta SSL ( Secure Socket Layer ). Questa REQUEST_LINE coincide esattamente con la nostra seconda alternativa ( sempre esclusa, naturalmente, la parte finale, che dobbiamo ancora riscontrare ):
dove:
Attenzione: il motore delle espressioni regolari, di default, è case sensitive ( distingue, cioè, tra lettere maiuscole e minuscole ). Quindi, se la nostra REQUEST_LINE includesse stringhe quali:
il motore REGEX non riconoscerebbe questa sequenza come una sequenza valida! In questo caso, visto che l'intero pattern è introdotto da un operatore di negazione (
che dovrebbe essere composta da:
Quindi, il primo percorso alternativo, contenuto nel primo subpattern annidato dell'espressione regolare, rappresenta la parte della REQUEST_LINE che comprende il metodo HTTP da utilizzare e la URL della risorsa da prelevare. Alcuni esempi:
Il modello di URL che l'espressione regolare tenta di rappresentare è quello riportato dalla RCF 2616:
A questo punto, sappiamo che il primo subpattern annidato cerca o una REQUEST_LINE classica ( con metodo HTTP, POST, GET, HEAD ), oppure una REQUEST_LINE per un metodo HTTP CONNECT, oppure una REQUEST_LINE per un metodo HTTP OPTIONS:
tutte scritte in caratteri minuscoli. Per vedere all'opera il motore REGEX, provate queste due semplici stringhe di riferimento, confrontate con il pattern che abbiamo visto fino ad ora, cioè quello compreso nel primo subpattern annidato. Se la stringa di riferimento fosse una delle seguenti:
il motore REGEX riscontrerebbe, rispettivamente, la stringa:
come facilmente prevedibile e ovvio. Ma se la nostra stringa di riferimento fosse:
il motore REGEX riscontrerebbe la stringa:
catturando anche la parte finale della REQUEST_LINE ( HTTP/1.0 ), la parte finale che dovrebbe essere espressa dalla parte del pattern che ancora non abbiamo analizzato. Perchè questo accade? Il motivo è molto semplice: se il motore REGEX incontrasse un carattere letterale "punto interrogativo", (
dove viene rappresentata una eventuale QUERY_STRING. Se, invece, il motore REGEX incontrasse un carattere letterale "cancelletto", (
che rappresenta un àncora HTML. Entrambi questi due subpattern escludono la presenza dei caratteri "spazio". Quindi, se il motore REGEX dovesse attraversare, con successo, uno di questi due subpattern, il motore REGEX si fermerebbe immediatamente prima dello spazio che separa la stringa della URL dalla stringa del protocollo ( HTTP/1.0 ). Se, invece, il motore REGEX fallisse nel riscontro di questi due subpattern, visto che entrambi i subpattern sono opzionali, il motore REGEX continuerebbe ad analizzare la stringa di riferimento, utilizzando l'ultima direttiva incontrata:
che indica un qualsiasi carattere ( compreso lo spazio, quindi ), ad eccezione dei caratteri letterali "punto interrogativo" e "cancelletto". Con questa impostazione, il motore REGEX è in grado di catturare l'intera stringa. Quindi, diventa necessario rappresentare, nel pattern, anche la stringa contenente la versione del protocollo utilizzato ( HTTP/1.0 ). Il controllo, ora, torna al subpattern principale, del quale ci resta da analizzare la parte finale:
Anche qui troviamo un operatore OR. Questo operatore OR indica un pattern completamente alternativo al pattern precedente. Il pattern precedente si conclude con la sequenza:
che, guarda caso, è in grado di rappresentare la stringa contenente il protocollo ( HTTP/1.0 ): uno spazio (
In alternativa a queste tre alternative, il pattern ce ne offre una quarta:
che sembra un pochino ridondante. Infatti, questo pattern finale permette di includere, nella REQUEST_LINE, la sola riga:
con il metodo HTTP
avrebbe, come conseguenza il fallimento del riscontro, visto che la versione del protocollo, nello standard HTTP, è obbligatorio. Anche senza quest'ultima parte di pattern, inoltre, una qualsiasi riga REQUEST_LINE che avesse un metodo
verrebbe normalmente riscontrata dal motore REGEX. Non riesco a comprendere il senso di questa parte finale del pattern, ma credo sia inutile soffermarmi ulteriormente su un aspetto davvero secondario di questa regola. Dopotutto, potrebbe semplicemente trattarsi di un errore, che non sembra poter inficiare l'intero processo.
A questo punto, analizzata l'intera espressione regolare, siamo in grado di confrontarla con la nostra REQUEST_LINE. Se il pattern venisse riscontrato ( ricordate l'operatore di negazione
che dice a ModSecurity di eseguire questa azione durante la fase 1 ( Analisi dei Request Header ), come abbiamo già visto nel precedente articolo. In questo momento, noi siamo proprio in fase 1. Le azioni successive sono:
L'azione
con il metodo HTTP scritto in caratteri maiuscoli, il riscontro del motore REGEX fallirebbe, restituendo un risultato positivo, a causa dell'operatore di negazione, posto all'inizio del pattern, attivando così le azioni comprese in ACTIONS. Una di queste azioni consiste proprio nel trasformare i caratteri maiuscoli in caratteri minuscoli. L'azione successiva:
non dice a ModSecurity di bloccare la transazione HTTP, come potrebbe sembrare, bensì di eseguire l'azione di tipo "disruptive" ( vedi il precedente articolo ) prevista dalla impostazione di default, impostata con l'ultima direttiva
dove l'azione di tipo "disruptive"
dove l'azione
Se, all'interno di un determinato account, potrebbe essere necessario impostare, direttamente in ciascuna regola, un'azione di tipo realmente "disruptive" ( con il blocco della transazione ), è possibile che in un altro account sia più saggio impostare un'azione di tipo "disruptive" meno catastrofica. L'azione
L'azione
L'azione
Quando si parla di "catena di regole", si parla di un insieme di regole, che ModSecurity dovrà attraversare in sequenza per restituire un unico risultato finale ( vedremo un esempio più tardi ).
L'azione
E' possibile specificare il grado di gravità del problema sia con il numero, sia con la descrizione testuale.
L'azione
L'azione
Le TAG sono stringhe testuali, che vengono legate alla regola corrente, al fine di una possibile categorizzazione. L'azione
Le variabili TX e RULE ( i nomi delle variabili, in ModSecurity, vengono scritti in caratteri maiuscoli, quando rappresentano la stringa sulla quale agirà l'operatore OPERATOR, in caratteri minuscoli, invece, quando inseriti nella parte della regola riservata alle azioni ) sono, in realtà, due "collection" di dati: variabili che contengono una lista di variabili, tutte relative alla transazione in corso, create da ModSecurity. La collection RULE contiene i campi
Le ultime due righe richiedono una spiegazione ulteriore. In queste due righe, infatti, si creano ( o si modificano ) due variabili:
sommando al loro valore attuale il valore della variabile:
dove
dove la direttiva
e dove il valore assegnato a ciascuna variabile è il valore incrementale, utilizzato da ModSecurity per aumentare il valore di ciascuna variabile, in occasione di ogni riscontro che abbia dato esito positivo ( un esito positivo, solitamente, coincide con un qualche problema ).
Quindi, ad ogni riscontro positivo, la variabile scalare
e non
Anche in questo caso, stiamo inizializzando una nuova variabile, il cui nome sarà composto dal nome della collection,
contiene tutti i riscontri avvenuti .
|
||||
ModSecurity: CRS 20, protocol violations, Regola 960911 | The .bit guides: original contents |