fbpx

Sql e code injection, ma anche no!

Sql e code injection, ma anche no!

di Giovanni Sodano Ottobre 30, 2010

Sql e Xss injection: impariamo a difenderci

Wikipedia dice che la SQL injection è una tecnica dell’hacking mirata a colpire le applicazioni web che si appoggiano su un database di tipo SQL e che sfrutta l’inefficianza dei controlli sui dati ricevuti. (continua a leggere su Wikipedia)

Io dico che la SQL injection (ed allo stesso modo ilCode injection) sono una vera e propriaseccatura.

Ad ogni modo, questo tipo di attacco può essere prevenuto prestando un pò di attenzione al codice che si scrive.

Per cominciare diciamo che per proteggersi dalla SQL injection è necessario filtrare i seguenti caratteri:

; -- + ' ( ) = > < @

e le seguenti parole SQL dedicate:

SELECT, INSERT, CREATE, DELETE, FROM, WHERE, OR, 
AND, LIKE, EXEC, SP_, XP_, SQL, ROWSET, OPEN, 
BEGIN, END, DECLARE 

poi, spiegherò come e perchè.

 

i database

DataBase costituiscono il fulcro dei nostri siti web dinamici, pertanto sono la parte più importante e più a rischio dei nostri progetti.

Gli hackers, tuttavia, attratti dalle informazioni (spesso confidenziali) che contengono i database, amano mettersi alla prova per scoprirne i bug (nel migliore dei casi) oppure danneggiarli e rubarne il contenuto.

Esistono diverse tipologie di database, che hanno sviluppato una loro specifica sintassi: i database più conosciuti sono: Access, MySql, SqlServer, Oracle, Interbase, Postgres.

 

le query

Le query, letteralmente interrogazioni, sono quelle istruzioni che uno sviluppatore usa per leggerescrivere o eliminare dati ad un a tabella in un database e spesso per passare in visualizzazione il risultato di tali operazioni.

Una query standard è del tipo:

SELECT * FROM TABELLA

che letteralmente sta per “seleziona tutti i campi dalla tabella”. E’ possibile, tuttavia filtrare la ricerca e renderla pià specifica aggiungendo altre istruzioni ed addirittura ordinarle in un qualsiasi modo:

SELECT CAMPO1, CAMPO2, CAMPO3 
        FROM TABELLA 
        WHERE CAMPO2 = 'criterio_ricerca' 
        ORDER BY CAMPO1 ASC

che letteralmente vuol dire “seleziona CAMPO1CAMPO2 e CAMPO3 dalla tabella dove il CAMPO2 è uguale a ‘criterio_ricerca’ ordinando i risultati in maniera crescente per CAMPO1″
e possibile collegare più filtri di ricerca usando le condizioni AND ed OR oppure combinare più query insieme usando la funzione JOIN.

Ora, chi legge questo articolo per trovare una risposta agli attacchi SQL e CODE injection, non deve pensare che io sia andato fuori tema, oppure non deve considerare quanto detto fino ad ora come un inutile prologo o una pesante introduzione: quanto detto fino ad ora è di fondamentale importanza per capire come avvengono gli attacchi e come prendere le dovute precauzioni.

 

attacchi di tipo injection

Il principio fondamentale su cui si basa questo tipo di attacchi è molto semplice, e lo si legge già nella parola che li contraddistingue: injection vuol dire “iniezione“, introduzione, cioè di codice esterno attraverso istruzioni SQL.

Ma come si fa ad introdurre del codice attraverso le pagine web?
E’ molto più semplice di quanto si possa pensare: nelle aree di testo dove inseriamo le keys per effettuare una ricerca, nel form di autenticazione di un sito.

Si possono addirittura introdurre pagine intere di codice dannoso sfruttando ad esempio i form di upload per caricare le foto o i files ed ultimo, ma non ultimo attraverso gli indirizzi URL.

 

sql injection

Immaginiamo uno scenario classico dove attraverso uno script stiamo cercando dei dati in un database: partiamo dunque da una TextBox nel quale abbiamo inserito la parola “pippo” per cercare tutti gli utenti con quel nome:

<%
dim camponome 'dichiaro la variabile
camponome = Request.Form("camporicerca")
 'recupero la parola chiave inserita dall'utente

sql = "SELECT * FROM TABELLA WHERE NOME = " & camponome & " "
set RS = conn.Execute(sql) 'eseguo l'istruzione SQL
%>

In esecuzione la query eseguita sarà:

SELECT * FROM TABELLA WHERE NOME = PIPPO

Ma cosa succederebbe se l’utente inserisse al posto di ‘pippo’ l’istruzione “; DROP TABELLA;” ?

In esecuzione la query diventerebbe:

SELECT * FROM TABELLA WHERE NOME = ; DROP TABELLA;

in pratica avremo come risultato tutti quei campi che hanno come campo nome un valore vuoto e avremo cancellato la tabella chiamata TABELLA.

E’ possibile usare questo sistema per aggiungere valori alla tabella, per cancellarla, per svuotarla e per far risultare vere istruzioni che non lo sono, riuscendo così ad accedere alle aree riservate del sito.

Va detto tuttavia, che non è semplicissimo per un hacker usare questo tipo di attacco per due motivi fondamentali: innanzitutto bisognerebbe che l’attacker conoscesse i nomi delle tabelle del nostro database, e poi, che avesse gli opportuni permessi per agire.

Per proteggerci da questo tipo di attacchi, comunque, è sufficiente filtrare i codici in entrata attraverso una funzione che possiamo scrivere, includere nelle pagine e richiamare ogni volta che ci serve.
Utilizzeremo la funzione, non soltanto per questo tipo di attacco, ma ogni volta che riceveremo dati in ingresso, per “pulirli” e per stare in pace con la coscienza!

<%
Function FixSQL(stringa) 
    stringa = Replace(stringa, "'", "''") 
    stringa = Replace(stringa, "%", "[%]") 
    stringa = Replace(stringa, "[", "[[]") 
    stringa = Replace(stringa, "]", "[]]") 
    stringa = Replace(stringa, "_", "[_]") 
    stringa = Replace(stringa, "#", "[#]") 
FixSQL = stringa 
End function 
%>

In questo modo, tornando all’esempio precedente:

<%
camponome = FixSQL(Request.Form("camporicerca"))
%>

Nell’esempio abbiamo filtrato solo alcuni caratteri, ma sarebbe opportuno creare una funzione in grado di filtrare tutti i caratteri SQL dedicati (alcuni dei quali li abbiamo visto all’inizio) e tutte le parole che potrebbero compromettere i nostri database.

Questo discorso è validissimo anche se parliamo di URL con variabili di pagine dinamiche.

In questo caso i dati non vengono presi dal form in entrata, ma direttamente dall’URL: non è l’utente ad effettuale la ricerca, ma siamo noi, in prima persona a passare le variabili.

Facciamo un esempio concreto: supponiamo di aver realizzato una pagina news.aspcon un elenco di notizie prese dal database.

Per comodità abbiamo deciso di mostrare solo i titoli, e cliccandoci sopra andremo in una pagina dedicata con la notizia per intero:

<%=titolonotizia%>

che in visualizzazione sarà:

Pippo vince alla lotteria

L’utente cliccando su “Pippo vince alla lotteria” andrà in questa pagina:

http://www.miosito.it/pag.asp?id=186

All’interno di quella pagina noi raccoglieremo il dato attraverso l’istruzioneRequest.QueryString e poi effettueremo una ricerca nel database:

<%
dim idnews 'dichiaro la variabile
idnews = Request.QueryString("id") 'recupero il valore passato in querystring

sql = "SELECT * FROM NEWS WHERE ID = " &idnews& " "
set RS = conn.Execute(sql) 'eseguo l'istruzione SQL
%>

In esecuzione la query eseguita sarà:

SELECT * FROM NEWS WHERE ID = 186

Ma cosa succederebbe se manipolassimo la query aggiungendo ad esempio “+ 1” all’URL?

In esecuzione la query diventerebbe:

SELECT * FROM NEWS WHERE ID = 186 + 1

Il sistema restituirebbe la news con ID = 187, e il nostro codice sarebbe tutt’altro che sicuro.

Proviamo a pensare a cosa succederebbe se l’URL venisse manipoato nel seguente modo:

http://www.miosito.it/pag.asp?id=186 union select nomeutente, password from logintable

Ammesso che la tabella contenente i dati di accesso si chiami logintable ed i campi di accesso si chiamino nomeutente e password, verrebbe stampato a video anzichè la news che ci aspettiamo i dati di accesso alla nostra area riservata.

A quel punto, possiamo aspettarci qualsiasi cosa!

Infine, per concludere il capitoletto sulle iniezioni dannose, proviamo a fare su google la seguente ricerca, scriviamo:

inurl:it/upload filetype:asp

Abbiamo appena detto a Google di cercare tutte quelle pagine in ASP (filetype:asp) nel cui URL ci sia it/upload (inurl:it/upload).

Ora sappiamo che solitamente la cartella UPLOAD la si usa per caricare foto, video, documenti ed altro, e per questo motivo possiede i permessi in scrittura.

Se noi quindi abbiamo realizzato una pagina che permette all’utente di caricare online il proprio curriculum vitae tale pagina userà un file che andrà a scrivere nella cartella UPLOAD il curriculum vitae caricato.

Ora pensiamo che invece di un curriculum vitae, un attacker carichi online una pagina web ASP o ASPX che recuperi dinamicamente tutte le informazioni relative al nostro database, i percorsi, le tabelle, i permessi, e tutto il resto.

Gli avremmo dato, in questo modo non soltanto il pieno controllo del nostro sito web, ma addirittura il controllo su tutti i siti web presenti sul server.

Per evitare tutto questo usiamo i soliti controlli, e prima di memorizzare o di uploadare qualsiasi cosa assicuriamoci che l’estensione del file sia esattamente quella che deve essere.

Controlliamo ad esempio che:

<%
if right(nomefile,4) <> ".jpg" then
response.write "Il file che stai cercando di caricare non è un'immagine."
response.write "Puoi caricare solo files con estensione .jpg"
response.end
end if
%>

 

xss: cross-site scripting

Meglio conosciuto come script injection o code injection consiste nell’introdurre nelle pagine dei nostri siti web (sia statici che dinamici) script in javascript, o VBScript in grado di alterare il comportamento di una pagina web.

Ma passiamo alla pratica: abbiamo il nostro blog, con i commenti degli utenti. Immaginiamo che un utente invece di scrivere il commento inserisca qualcosa del tipo:

location='http://www.nostrosito.it/';

In questo modo, chiunque aprirà i commenti del nostro articolo sarà reindirizzato verso si sitoweb www.nostrosito.it

Questo esempio, che a prima vista sembra poco dannoso, può essere sfruttato ad esempio per reindirizzare gli ignari visitatori presso una pagina del tutto simile a quella originale, ma che in realtà è in grado di leggere e memorizzare i cookie rilasciati dagli utenti, che li può spingere a riautenticarsi memorizzando nome utente e password, a lasciare il proprio indirizzo e-mail e chi più ne ha più ne metta.

Per difenderci da questi attacchi, la soluzione più semplice è qella di conrollare sempre il contenuto proveniente dall’esterno ed assicurarci che non ci siano tag o caratteri speciali che potrebbero compromettere le nostre pagine web.

Facciamo riferimento alla funzione injectionControl:

<%
Function injectionControl(str)
   Dim tmpstr ' variabile temporanea
   tmpstr = str 'valore parametro della funzione

   tmpstr = replace(tmpstr, "", "") 'elimino il tag 
   tmpstr = replace(tmpstr, "", "") 'elimino il tag 

   injectionControl = tmpstr 'restituisco l'output della funzione
End function
%>

In questo modo abbiamo banalmente elimintato i tag  e  presenti nel codice esterno.

Naturalmente, per la serie “i controlli non sono mai troppi”, possiamo attraverso javascript, o codice lato server intervenire addirittura prima ancora di salvare o inviare i dati.

Se ci aspettiamo un input numerico, ad esempio potremmo usare la funzione ASPisnumeric() o controllare una mail attraverso una RegExp

 

Attenzione!!!

I contenuti riportati in questo articolo non vogliono in nessun modo esortare i lettori a provare ad attaccare siti ed applicazioni web.
Lo scopo, infatti, è quello di rendere sviluppatori ed utenti consapevoli dei rischi cui si può incorrere navigando in internet.
Il linguaggio tecnico dell’articolo fa riferimento al linguaggio server ASP, ma vale per tutti gli altri linguaggi di programmazione comuni.
Gli spunti e gli esempi, oltre che dall’esperienza personale, sono stati tratti dalla rete.

Condividi questo contenuto sui Social

Iscriviti per rimanere in contatto con me!

Niente spam, promesso!

Lasciami un commento, te ne sono grato.

La tua email address will not be published. Required fields are marked *