Recentemente, giornali e opinionisti si sono occupati delle vulnerabilità informatiche dei tre siti ufficiali del Movimento Cinque Stelle: la piattaforma Rousseau, il blog di Grillo e il blog delle Stelle. I fatti sono ormai abbastanza chiari: il primo sito è stato forzato a inizio agosto da un hacker benigno noto come Evariste Gal0is, che ha comunicato la vulnerabilità senza sfruttarla, e gli altri dall’hacker rogue_0, decisamente meno collaborativo e che sfrutta il suo accesso illimitato da un tempo che sembra essere abbastanza lungo. Bisogna forse essere un po’ esperti di informatica per capire come mai le vulnerabilità riscontrate sono così gravi. E come mai, combinate con qualche altro fattore, possono portare a risultati gravissimi.
Prima di analizzarli, chiariamo due termini utilizzati nel resto dell’articolo: quando due computer comunicano attraverso Internet, ad esempio quando il computer dei lettori invia una richiesta a theWisemagazine.it per vedere questo articolo, il computer che effettua la richiesta si dice client, mentre si dice server “il computer che sta dall’altra parte”, quello che si occupa di gestire la richiesta.
Le premesse
Come regola di base, ogni sistema informatico è vulnerabile. Non esiste una maniera per creare un sistema che sia completamente sicuro e al contempo utilizzabile. Per i sistemi informatici vale la regola che vale per gli edifici privati: più gente deve poterci entrare, più è difficile garantire la sicurezza. Controllare chi entra durante un concerto con centomila spettatori è più difficile che farlo durante un’interrogatorio di polizia, in una stanza in cui ci devono essere solo quattro persone. Il sistema completamente sicuro è una scatola chiusa in cui non può entrare nessuno. Inespugnabile, certo, ma anche inutile, visto che a quel punto nemmeno amministratori e utenti possono utilizzarlo. Per operare su un sistema bisogna mettere una porta, e in ogni porta c’è una serratura vulnerabile. Ci sono serrature più vulnerabili e altre meno, ma tutte lo sono.
Alcune di queste vulnerabilità sono più o meno note e più o meno gravi nelle conseguenze. In particolare, la prima vulnerabilità riscontrata – una delle tante, in realtà, ma quella più grave in assoluto – è la SQL injection, una ben nota problematica dei database.
[restrict userlevel=”subscriber”]
Cosa è un database
Un database è un programma a sé stante che si occupa di tenere delle informazioni. Queste informazioni possono essere di vari tipi: numeri interi o decimali, dati booleani (vero o falso), date e stringhe di caratteri. I database sono particolarmente apprezzati per due motivi. Il primo è la schematicità: i dati sono conservati in “tabelle”, del tutto analoghe a quelle che si possono fare su Excel. Il secondo è la loro velocità a inserire nuove informazioni, cancellarne di vecchie o effettuare ricerche anche molto complesse, come può essere «trovami tutti i pagamenti effettuati fra il 5/9/2011 e il 10/9/2011 di almeno 500 euro passati attraverso i circuiti di Unicredit il cui pagatore possiede una Fiat Punto rossa immatricolata nel 2015». “Interrogare un database” vuol dire chiedere al database di effettuare un’operazione: inserire, cancellare, cercare, aggiornare, calcolare. Dare un’istruzione a un database significa effettuare un’interrogazione. Questo stesso sito, theWise Magazine, utilizza un database per tenere in memoria gli utenti registrati, per esempio.
Nell’informatica parecchie cose sono cambiate nel tempo – praticamente tutto, in effetti – ma di tutti gli strumenti di largo uso esistenti, uno dei pochi a rimanere sostanzialmente invariato è proprio il linguaggio utilizzato per interrogare i database. È stato definito negli anni Settanta, si chiama SQL (Structured Query Language, cioè linguaggio per ricerche strutturate) – e da allora è rimasto praticamente sempre quello. La struttura di un comando, chiamato generalmente query, è molto semplice: c’è l’istruzione da eseguire e un carattere “;” per segnalarne la fine. Il lavoro del server è quindi semplice, per un programmatore: se l’istruzione da eseguire per registrare un nuovo utente è, ad esempio, “INSERT INTO utenti (‘nomeutente’)”, il server sostituisce “nomeutente” con il nome che ha ricevuto e poi passa la query così ottenuta al database. Se io dicessi a un sito di chiamarmi “Rodolfo Bevione”, tramite un normalissimo form come quelli usati per la registrazione, il server invierebbe al proprio database (che, di nuovo, è un programma separato) un comando di questo tipo:
INSERT INTO utenti ('Rodolfo Bevione');
Fin qui, nulla di strano. Ma che succederebbe se io dicessi di chiamarmi, per esempio, “Rodolfo Bevione’); DROP TABLE (‘utenti”?
Il risultato sarebbe più inquietante. Il server infatti metterebbe il nome ricevuto nella query di inserimento. Il nome ricevuto è un po’ malizioso, e infatti al database viene inviato questo:
INSERT INTO utenti ('Rodolfo Bevione'); DROP TABLE ('utenti');
Grazie al punto e virgola,vengono interpretati come due comandi separati ed eseguiti in sequenza. DROP TABLE, per chi se lo stesse chiedendo, serve a cancellare una tabella: in questo caso, avremmo appena cancellato l’elenco degli utenti. Un’operazione di questo tipo è precisamente quanto è accaduto a Rousseau, il “Sistema Operativo a 5S” (che non è un sistema operativo, tra l’altro). È stata utilizzata questa vulnerabilità anche sul Blog di Grillo, ma in questo ultimo caso la situazione è ancora più grave.
Come già detto, il linguaggio SQL è rimasto sostanzialmente lo stesso da quando è stato ideato, circa quarant’anni fa, e quindi questa vulnerabilità è estremamente conosciuta.
Per risolvere questa vulnerabilità ci sono diverse strade, tutte molto semplici da percorrere.
- Stabilire diversi livelli di privilegio. Il database blocca automaticamente le richieste per cui un utente non ha l’autorizzazione. I database implementano di base una funzionalità di questo tipo; l’unica cosa da fare è, appunto, definire cosa possono fare i vari gruppi di utenti.
- Esplicitare i caratteri sospetti, tecnica detta escaping in gergo, prima di inviare la query, in modo che il database non venga confuso da comandi fittizi. Oppure, in modo più radicale, impedire direttamente agli utenti l’utilizzo di tali caratteri. Come approccio è abbastanza sconsigliabile: oltre a essere brutto, è anche facile sbagliarsi e dimenticarne qualcuno. Se però l’alternativa è il niente, va benissimo questo.
- Le query parametrizzate. Sono la strada generalmente più utilizzata, la più semplice da scrivere e mantenere, la più elegante da vedere e la più sicura in assoluto. Poiché sono un po’ più tecniche, per chi volesse approfondire rimando a questo articolo.
Tutte queste sono soluzioni molto semplici da implementare. Il punto ancora più importante è però un altro: spesso i programmatori nemmeno si devono curare di questo problema. La comunicazione fra database e server è infatti normalmente gestita separatamente da una libreria che traduce i due diversi linguaggi della programmazione e dei database: ce ne sono tantissime, gratuite e disponibili per diversi linguaggi, e sono concepite in modo da essere immuni alle SQL injection. Il fatto che né il blog di Grillo né Rousseau avessero protezioni contro questa vulnerabilità – nonostante fosse così nota e fosse così facile proteggersi – è estremamente grave per gli utenti ed è possibilissimo abbia inficiato votazioni passate. Ed è anche possibile che tali dati siano stati distribuiti a terzi.
Ma parliamo delle password
Le password sono la nota più dolente nel difficile rapporto fra amministratori e utenti. Gli amministratori si devono assicurare che solo chi ne ha il diritto effettui certe operazioni e, non potendo controllare di persona, impongono agli utenti di utilizzare questa parola segreta per assicurarsi che questi siano proprio chi affermano di essere. Gli utenti, peraltro, spesso usano le stesse password per più siti diversi. Conoscere una password vuol dire avere il massimo potere sull’account di una persona e possibilmente anche negli altri siti che questa frequenta. E quindi gli sviluppatori utilizzano tutte le misure necessarie per proteggerle, perderle sarebbe gravissimo.
Quali sono queste misure?
La prima misura, la più recente, è l’utilizzo dell’HTTPS per le comunicazioni. Nonostante questo sistema sia in realtà abbastanza complesso a livello teorico, a livello pratico è semplice da implementare per gli sviluppatori e assolutamente indifferente per gli utenti -nel senso che fra navigare in un sito normale e in un sito che utilizza HTTPS non c’è nessuna differenza visibile. La differenza enorme è a livello di sicurezza: i dati inviati sono sicuri sia dalle manomissioni che dalle intercettazioni. Essere intercettati, se si utilizza un wifi senza password, è sorprendentemente semplice: pensateci, la prossima volta che scroccate internet al vicino, perché magari sta solo aspettando l’occasione per svuotarvi il conto in banca.
Al di là dei tecnicismi, il sistema si basa su due chiavi, una a disposizione del server e l’altra a disposizione del client. In un sistema di questo tipo, con la mia chiave posso decifrare i messaggi che ricevo e cifrare quelli che invio, e questo vale anche per il mio partner. I dati così inviati – per esempio, una password – non possono essere intercettati né modificati da qualcuno che si mettesse in ascolto. O meglio, si possono intercettare, ma quello che si vede è ciarpame incomprensibile, come tutti i testi sottoposti a crittografia: provare per credere.
La seconda misura è anche quella più vecchia, più usata e assolutamente imprescindibile: il server semplicemente non conosce la password. Questo è, per inciso, il motivo per cui su nessun sito esiste il pulsante “recupera password”. Le password non sono salvate da nessuna parte. Se ne può impostare una nuova, ma non si può recuperare quella vecchia. In questo modo, anche in caso qualcuno riuscisse ad avere accesso al database non potrebbe comunque leggere le password.
Ma allora come fa il sito a riconoscere quando una password è giusta?
Il sito riconosce le password perché su database non le salva così come sono, ma salva degli hash. Un hash è, in parole molto povere, una serie di caratteri di lunghezza prefissata, e questa serie di caratteri è calcolata matematicamente a partire da qualcos’altro: un testo, un file, un numero. Provare qui per vederlo in azione.
Essendo un processo matematico, lo stesso testo darà sempre lo stesso hash, e due hash uguali sono stati prodotti dallo stesso testo iniziale. Ma questo non vuol dire che l’operazione sia invertibile: calcolare l’hash a partire da un testo è possibile, ricostruire il testo originario a partire da un hash invece no. In termini tecnici, è un processo con perdita di informazione.
Quindi, quando inserisco una password, questa non viene salvata da nessuna parte e non è possibile recuperarla in futuro: ne viene immediatamente calcolato l’hash e viene fatto il paragone fra l’hash che ha calcolato e quello presente nel database. Dato che dallo stesso testo deriva sempre lo stesso hash, se quello calcolato corrisponde a quello inserito nel database, vuol dire che la password inserita è uguale a quella originale e quindi è consentito l’accesso.
Quello che c’è nel database, in altre parole, è soltanto una stringa di 128 caratteri apparentemente casuali. E non esiste modo per capire qual è la password che li ha generati – se non, appunto, provarle tutte finché non si trova una corrispondenza.
Quindi tramite HTTPS la password non può essere intercettata per strada, e con l’hashing la password non si può scoprire leggendo il database. A questo punto l’amministratore ha -circa – fatto tutto quello che poteva fare: il sistema è sicuro, perché l’unica persona che può sapere la password è l’utente. Implementare queste funzionalità, che risolvono sostanzialmente parecchi problemi legati alla sicurezza delle credenziali, è estremamente semplice: l’hashing è una tecnica che richiede solo di scrivere due righe di codice in più. Implementare l’HTTPS richiede di sbrigare un po’ di questioni burocratiche – deve essere rilasciato un certificato – e può volerci qualche giorno, ma anche in questo caso la difficoltà di implementazione è nulla.
Sono misure basilari, semplicissime ed efficaci, tuttavia il blog di Beppe Grillo non ne utilizzava nessuna. Le password erano (e probabilmente lo sono ancora) salvate in chiaro, e sono ancora inviate in chiaro. Per Rousseau il discorso è un po’ diverso: utilizza HTTPS e le password nel database erano effettivamente cifrate. Però veniva utilizzato un algoritmo del 1980 chiamato DES, che oggi si può forzare in una decina di secondi.
Ci sono altre vulnerabilità?
In realtà sì, e non sono meno gravi, sono solo più difficili da spiegare.
L’hacker che ha effettuato il primo attacco sostiene inoltre che ci fossero altre vulnerabilità, come quella ad attacchi di tipo XSS. Poiché metterli in pratica richiede un po’ più lavoro che scrivere una query ed è una questione un po’ più tecnica, chi è interessato può approfondire qui. In sintesi, comunque, JavaScript è il linguaggio che viene utilizzato per rendere dinamici i siti web, che altrimenti sarebbero statici come lo erano nel 1996. Tramite JavaScript è possibile fare un po’ di tutto su una pagina web – nascondere alcune parti, mostrarne altre, riprodurre i filmati e così via. E anche eseguire codice maligno. XSS vuol dire che è teoricamente possibile che altre persone facciano scaricare il proprio codice tramite il sito di Beppe Grillo e farlo eseguire come se fosse affidabile. Quindi, per esempio, anche se le altre vulnerabilità fossero sistemate, io potrei far eseguire agli utenti uno script che mi invia – indirettamente – in tempo reale le password mentre queste vengono digitate.
In secondo luogo, normalmente i server conservano lo storico delle operazioni su un file chiamato file di log. Questo file tiene traccia di quello che accade al server e serve a scoprire i problemi di sicurezza il più presto possibile dopo il loro primo utilizzo. A quanto pare né il blog di Grillo né Rousseau ne compilano uno o, se lo compilano, nessuno lo guarda. Il firewall non ha bloccato queste operazioni sospette. Le password di Rousseau, inoltre, sono cifrate ma lunghe al massimo otto caratteri, e quindi più vulnerabili. Otto caratteri vuol dire anche il classico formato delle date “giorno mese anno”. Cosa succede se si prova a sfruttare questo fatto? Un generatore casuale di numeri ne ha indovinate il 5%. Insomma, ci sono un po’ di problemi gravi su questioni basilari, e questo non fa ben sperare sul modo in cui può essere gestito il resto della piattaforma online.
[/restrict]