Proteggere un sito con mod_security

ModSecurity  è un modulo aggiuntivo per Apache2 che consente di ispezionare, ad ogni livello o fase della transazione http, i vari parametri che entrano in gioco e che la caratterizzano e di prendere eventualmente provvedimenti sulla base di regole fornite nel file di configurazione.
Le fasi della transazione http esaminate sono le seguenti e precisamente

  • Request headers (fase 1)

In questa fase sono disponibili gli header della richiesta http che effettua il client, come esempio in questa fase abbiamo a disposizione i cookie, lo user-agent, i parametri in GET

  • Request body (fase 2)

In questa fase è disponibile il body della richiesta http ovvero tutto quello che segue gli header, esempio i parametri in POST, oppure un file che si sta uploadando sul server

  • Response header (fase 3)

In questa abbiamo gli header in risposta che  il server intende trasmettere  al client (es. gli header per settare i cookie, la cache, etc)

  • Response body (fase 4)

In questa fase abbiamo a disposizione anche il corpo della risposta che il server intende mandare al client, esempio tutta la pagina html

  • Logging (fase 5)

Questa è una pseudo-fase finale, può essere utile per loggare la richiesta, che comunque è già stata mandata

Tutte le fasi meno che l’ultima sono bloccabili, ovvero si può configurare mod_security in modo da fare in modo che la richiesta non segua il suo corso normale.

L’ eventuale azione di blocco della richiesta andrebbe presa prima possibile, nella fase 1 o 2, per fare in modo che l’eventuale client o bot disturbatore non vada a consumare troppe risorse.

Le fasi 3 o 4 servono sostanzialmente per controllare quello che il nostro server sta per trasmettere al client:  l’utilizzo principale è quello di controllare che i dati non contengano script dannosi per il client.

Questo può essere molto utile al webmaster di un sito che mette a disposizione blog o spazi a utenti che non conosce e vuole in qualche modo bloccare eventuali pagine ospitate  che contengono script o codice indesiderato.

La configurazione di mod_security si basa su regole che prendono in considerazione le variabili a disposizione in quella fase, applicano delle operazioni su tali variabili (dopo averle eventualmente pre-elaborate con le funzioni di trasformazione) ed eventualmente eseguono delle azioni se le operazioni hanno esito positivo.

Tanto per capire la potenza e la configurabilità dell’oggetto, è possibile indicare come operazione  uno script  in linguaggio LUA, questo rende possibile l’implementazione di filtri di qualsiasi tipo.

Le azioni sulle regole possono essere omesse, in quanto può essere specificata un’ azione di default.

Le azioni disponibili consentono di bloccare la richiesta  ( disruptive actions ), di fare qualcosa ma non bloccare la richiesta ( non-disruptive actions ), di modificare il flusso delle regole ( flow actions ), o azioni informative o dichiarative  ( meta-data actions e data actions).

La tipologia di ogni azione è descritta nella documentazione ufficiale.

Ma veniamo al dunque con un esempio pratico.

Ammettiamo di avere un sito che accetta commenti ma che non ha un sistema di filtri spam molto efficiente, per cui siamo stati costretti a pre-moderare i commenti ma con tutto questo nella coda di moderazione finisce sempre qualcosa di indesiderato.

Nell’esempio ispezionando i commenti indesiderati notiamo che la provenienza è quasi sempre da IP russi o ucraini e che spesso contengono link a siti che vendono medicinali o siti di gioco online.

Un set di regole potrebbe essere questo, il set di regole è stato inserito nella sezione VirtualHost del sito di esempio in questione.

<IfModule security2_module>

  # accendiamo SecRule
  SecRuleEngine On
  # abilitiamo l'ispezione del body request ( necessario per i parametri in post)
  SecRequestBodyAccess On
  # setto il body a un numero alto dato che il sito prevede upload di foto
  SecRequestBodyLimit 9999999
  SecRequestBodyNoFilesLimit 9999999
  SecRequestBodyInMemoryLimit 131072
  # non ci interessa esaminare il body della risposta
  SecResponseBodyAccess Off

  # l'azione di default è negare e loggare
  SecDefaultAction "phase:2,deny,log"

  # setto il nome del db degli IP che userò per filtrare i commenti
  SecGeoLookupDb /usr/local/geo/data/GeoLiteCity.dat

  # con queste regole disattivo l'invio di commenti da parte di IP russi o ucraini
  SecRule &ARGS_POST "@eq 0" "skipAfter:AFTER_GEO_CHECK,pass,nolog"
  SecRule REMOTE_ADDR "@geoLookup" "chain,deny,msg:'Geo filter on %{REQUEST_BODY}'"
  SecRule GEO:COUNTRY_CODE "@rx RU|UA"
  SecMarker AFTER_GEO_CHECK

  # con questa regola blocco tutti i commenti che contengono le parole specificate, ignorando se minuscole o maiuscole
  SecRule ARGS "pharmacy|casino|viagra|cialis|prescriptions|drug" "t:lowercase"

</IfModule>

Nell’esempio il file che mappa gli Ip con le informazioni geografiche è GeoLite City di MaxMind.

Ora probabilmente l’esempio è un pochino estremo in quanto non consente ad IP russi o ucraini di fare commenti ma è possibile modificare la regola in modo che sia meno selettiva, per questo dal filtro  vengono loggati  i commenti bloccati  nell’error-log: Se cominceranno ad arrivare commenti validi potremmo agire sulle regole.

Intanto ecco una linea del file di log dove si vede uno spammer appena catturato.

Come si vede  il filtro ha pizzicato un IP russo o ucraino, il commento, come si evince dal payload, è sicuramente spam: il filtro ha fatto il suo lavoro.

Installare mod_security è molto semplice e si trovano parecchie guide in giro, in Ubuntu è presente nel repository standard ed è sufficiente usare il comando

apt-get install libapache-mod-security

Questo è solo un piccolo esempio di quello che è possibile fare con ModSecurity, le sue potenzialità sono enormi, degno di nota è il  ModSecurity Core Rule Set Project, che mantiene un set di regole per ModSecurity  utili a fornire una efficace protezione per le vulnerabilità spesso presenti nelle applicazioni web.

Se volete approfondire un buon inizio sono i riferimenti riportati sotto.

Riferimenti