Contattaci

SQL Injection

sql injection
  • Data: 30 Gennaio 2019
  • Autore: Gabriele Seroni
  • Categorie

  • Giuneco Tech

    Il nostro settore richiede uno studio continuo e una forte attenzione all’innovazione. Incentiviamo quindi dei programmi formativi annuali per tutti i componenti del team, con ore dedicate (durante l’orario di lavoro) e serate formative sia online che in presenza. Sponsorizziamo eventi, sia come partner che semplicemente come partecipanti, e scriviamo articoli su quello che abbiamo imparato per essere, a nostra volta, dei divulgatori.

    Vai alla sezione Team
  • La SQL injection è una tecnica di code injection che aggredisce applicazioni web facenti utilizzo di un database SQL: andando ad inserire frammenti malevoli di codice SQL all’interno di campi di input si va modificare il comportamento delle query sul database all’insaputa dello sviluppatore.
    La SQL injection sfrutta, nella maggioranza dei casi, vulnerabilità del codice dell’applicazione, come: una mancata validazione degli input, un mancato filtraggio dei dati mandati da un client al server, oppure una costruzione errata di query all’interno della nostra applicazione, con parametri non fortemente tipizzati.

    Il suo utilizzo è, per quanto appena detto, spesso veicolato da applicazioni web, ma in realtà può essere usato per attaccare qualsiasi tipo di database SQL.
    Questa tecnica è stata considerata da Open Web Application Security Project una delle 10 maggiori vulnerabilità delle applicazioni web nel 2007 e nel 2010, mentre dal 2013 ad oggi è stato considerato il numero uno degli attacchi sulla OWASP top 10.
    Il “primato” è dovuto sostanzialmente a 3 fattori:

    • Facilità di identificazione: Quasi tutte le fonti input di dati possono essere un vettore di iniezione. Capire l’effettiva vulnerabilità, come vedremo successivamente, è molto semplice e rapido.
    • Facilità di sfruttamento: Basta una basilare conoscenza di SQL o l’utilizzo di numerosi tool gratuiti reperibili in rete per poter effettuare un attacco.
    • Pericolosità: varia a seconda del business dell’applicazione ma, in linea generale, la manomissione, perdita o divulgazione dei dati presenti nel nostro DB è uno dei peggiori scenari a cui potremmo dover far fronte.

    Negli ultimi anni alcuni attacchi di questo tipo dimostratosi particolarmente gravi hanno messo in luce come, pur avendo a disposizione strumenti sempre più avanzati per ovviare a tale vulnerabilità, tantissimi software tuttora non utilizzino soluzioni allo stato dell’arte per garantire sicurezza sotto questo aspetto.
    Come detto precedentemente, una delle principali fonti di preoccupazione verso un attacco SQL Injection è la sua pericolosità e di seguito sono riportati gli ambiti in cui un attacco come questo può agire:

    • Confidenzialità: informazioni sensibili potrebbero entrare in possesso del soggetto attaccante non autorizzato. Questo può avvenire qualora, oltre all’essere stati attaccati in maniera efficace, non avessimo adottato efficaci algoritmi di criptaggio permettendo così all’attaccante di avere le informazioni in un formato intelligibile.
    • Disponibilità: l’attacco potrebbe rendere il nostro servizio non utilizzabile (a seconda dell’entità ed alla tipologia dell’attacco stesso). In questa casistica rientrano gli attacchi DoS, dove si fanno esaurire deliberatamente le risorse di un sistema informatico fino a renderlo non più in grado di erogare il servizio ai client. Esempi possono essere script che effettuano inserimenti o update massivi di dati, “lock” su tabelle, o query molto dispendiose come SELECT su tabelle molto grandi.
    • Integrità: rientra in questa casistica l’attacco che porta alla manomissione (inserimento, modifica, cancellazione) dei dati presenti sul nostro database. A seconda del tipo di business dell’applicazione, questa situazione spesso può comportare anche una mancata disponibilità del servizio stesso poiché si è costretti a metterlo offline fino ad un restore completo di dati affidabili.

    Tipologie

    Un aspetto fondamentale da conoscere in materia di SQL Injection è che non esiste solo una tipologia di attacco, ma questi si dividono in principalmente 3 categorie:

    Error Based

    Un tipo di attacco basato su errori sfrutta la scarsa gestione di quest’ultimi in un’applicazione, infatti consiste nell’attivare di proposito errori nel database trasmettendo valori di input non validi.
    In molti casi infatti le eccezioni generate dal database SQL possono essere molto parlanti per quanto riguarda la struttura dello stesso ed il tipo di dati salvati.
    Affinando ed arricchendo sempre di più la query malevola, in base alle informazioni che siamo riusciti a reperire dalle eccezioni precedenti, potremmo avvicinarci ad ottenere una stringa iniettabile capace di estrapolare o manomettere dati.
    Questo tipo di approccio può portare al risultato atteso in relativamente poco tempo, ma necessita obbligatoriamente che l’applicazione sia configurata in modo da visualizzare (o comunque ritornare al client in un qualche modo intelligibile) gli errori generati dal database.

    Union Based

    L’iniezione SQL basata su unione consente di estrarre informazioni dal database estendendo i risultati restituiti dalla query originale.
    In questa modalità viene fatto utilizzo dell’operatore UNION per combinare il risultato di due o più istruzioni SELECT in un singolo risultato che viene poi restituito come parte della risposta al client.
    Il principale vincolo di questo tipo di attacco è dovuto al dover conoscere esattamente la struttura della query originale e replicarla su quella “aggiuntiva”.
    Proprio per quest’ultimo motivo è spesso preceduta da vari attacchi “error based” per cercar di capire la struttura della query originale.

    Blind Injection

    Nelle due precedenti modalità è necessario che alcune condizioni, quali l’abilitazione degli errori a video o la possibilità di utilizzare l’operatore UNION nelle query, siano soddisfatte per poter essere eseguiti.
    Quando ciò non è possibile c’è un’ultima tipologia di attacco nella quale un attaccante può fare affidamento: la Blind Injection.
    Questa variante è la più efficace ma al contempo la più difficile da effettuare, infatti, come suggerisce il nome (“iniezione cieca”), si procede alla cieca.
    In questo caso è più che utile un esempio:

    Consideriamo di avere un indirizzo costruito in questo modo:

    localhost/Alunni?orderBy=nome

    possiamo immaginare che la query eseguita possa essere qualcosa del tipo

    select * from alunni order by nome

    l’attaccante potrebbe manomettere il parametro in query string per ottenere informazioni non desiderate

    localhost/Alunni?orderBy=case when(select top 1 from sys.tables)='foo' then nome else   cognome end

    In questo semplice modo a seconda di come verranno ordinati gli elementi restituiti, l’attaccante sarà a conoscenza della presenza o meno della tabella che sta cercando nel frammento di query iniettato.

    Con l’aumentare dei tentativi effettuati aumenteranno sempre più anche le informazioni in possesso dell’attaccante.

    Come è facile intuire il principale limite di quest’ultima metodologia è il tempo impiegato per ottenere le informazioni ma, anche in questo caso, ci sono una grande quantità di tool gratuiti in grado di automatizzare il processo.

    Come Prevenire

    Fortunatamente esistono varie tecniche che possono essere utilizzate per prevenire attacchi di SQL Injection, ma per far sì che siano realmente efficaci dobbiamo occuparci di tutti i componenti coinvolti: il server, le singole applicazioni ed il Database Management System.

    1. Validazione degli “untrusted data”: Potenzialmente ogni dato inviato da un client potrebbe essere stato manomesso o contenere valori malevoli, per questo dovrebbe essere correttamente validato sia sintatticamente che semanticamente. L’utilizzo di Regular Expression “lato server” è molto utile in questo caso.
    2. Tipizzazione forte nelle query: Tantissimi attacchi SQL Injection sfruttano una mancata tipizzazione dei parametri nelle query utilizzate dallo sviluppatore. Spesso è facile per uno sviluppatore, generalmente per colpa della scarsità di tempo a disposizione, cadere nell’errore di costruire una query direttamente nel codice del software senza tipizzare i parametri, in un formato non molto lontano da questo:
      var query = “select * from clienti where email = ” + email;
      L’utilizzo di stored procedures (tecnologia non nuovissima ma ugualmente utile a tale scopo) o dei più moderni ORM (Object-Relational Mapping) viene incontro a tale esigenza e porta lo sviluppatore a tipizzare sempre i parametri utilizzati per le interrogazioni, limitando non poco la vulnerabilità.
    3. Utilizzo di utenti con privilegi limitati: un’ottima tecnica di prevenzione è quella di evitare la creazione di un singolo utente SQL con privilegi illimitati, ma di prediligere la creazione e l’utilizzo (nei componenti software) di più utenti con differenti abilitazioni. In questo modo è possibile “ritagliare” un sottoinsieme di privilegi in base all’utilizzo che ne viene fatto negli applicativi. In questo modo, ad esempio, eviteremo che in un software atto solo alla lettura di alcune tabelle, ed alla successiva presentazione del risultato a video, sia utilizzato un utente con privilegi di scrittura limitando le possibilità di manomissione e/o corruzione dei dati.
    4. Criptare dati sensibili: l’utilizzo di algoritmi di cifratura per quanto concerne sia la trasmissione dei dati che la loro storicizzazione deve essere sempre alla base di qualsiasi software che immagazzini dati sensibili. Un’implementazione di questo tipo ci garantisce che, anche qualora un attaccante riuscisse ad entrare in possesso di tali informazioni, essi non siano in un formato comprensibile e/o utilizzabile in nessun modo.
    5. Disabilitare errori a video: questo punto è direttamente legato alla tecnica di Injection basata su errori. Generalmente nei file di configurazioni di applicazioni e servizi web è presente un parametro apposito per disabilitare la visualizzazione delle eccezioni non gestite. Questa funzionalità, infatti, dovrebbe essere utilizzata solo per fini di debug in ambienti di sviluppo. È otremodo importante ricordarsi (soprattutto per quanto concerne servizi web) di non settare manualmente nei nostri messaggi di risposta ai client l’eccezione “catchata” nell’applicativo.
    6. Utilizzo di firewall: un ultimo, ma non per rilevanza, componente utilizzabile come prevenzioni di attacchi è un Web Application Firewall. Un WAF è un firewall per applicazioni web che usano il protocollo HTTP ed applica un set di regole che, in genere, riguardano attacchi comuni come il cross-site scripting (XSS) e la SQL Injection. Per quanto riguarda le vulnerabilità inerenti a questo articolo ci basti sapere che un firewall di questo tipo generalmente utilizza come filtro una serie di Regular Expression per validare a monte i parametri in ingresso delle chiamate HTTP intercettando in questo modo le richieste potenzialmente pericolose.