Esercitazione SQL

SQL HOME Introduzione SQL Sintassi SQL Seleziona SQL SQL Seleziona distinto SQL dove SQL e, o, no Ordina SQL per Inserisci SQL in Valori nulli SQL Aggiornamento SQL Elimina SQL SQL Seleziona in alto SQL Min e Max Conteggio SQL, media, somma Mi piace SQL Caratteri jolly SQL SQL In SQL tra Alias ​​SQL Join SQL Join interno SQL Join sinistro SQL SQL Right Join SQL Full Join SQL Self Join Unione SQL Raggruppamento SQL per SQL Avere SQL esiste SQL Qualsiasi, Tutti SQL Seleziona in Inserisci SQL in Seleziona Caso SQL Funzioni SQL Null Stored procedure SQL Commenti SQL Operatori SQL

Database SQL

SQL Crea DB SQL Drop DB DB di backup SQL SQL Crea tabella Tabella di rilascio SQL SQL Alter tabella Vincoli SQL SQL non nullo SQL unico Chiave primaria SQL Chiave esterna SQL Controllo SQL SQL predefinito Indice SQL Incremento automatico SQL Date SQL Viste SQL SQL Injection Hosting SQL Tipi di dati SQL

Riferimenti SQL

Parole chiave SQL Funzioni MySQL Funzioni di SQL Server Funzioni di accesso MS Riferimento rapido SQL

Esempi SQL

Esempi SQL Quiz SQL Esercizi SQL Certificato SQL

Iniezione SQL


SQL Injection

SQL injection è una tecnica di iniezione di codice che potrebbe distruggere il database.

L'SQL injection è una delle tecniche di web hacking più comuni.

SQL injection è il posizionamento di codice dannoso nelle istruzioni SQL, tramite l'input di una pagina web.


SQL nelle pagine Web

L'iniezione SQL di solito si verifica quando chiedi a un utente un input, come il suo nome utente/id utente, e invece di un nome/id, l'utente ti fornisce un'istruzione SQL che eseguirai inconsapevolmente sul tuo database.

Guarda il seguente esempio che crea SELECTun'istruzione aggiungendo una variabile (txtUserId) a una stringa di selezione. La variabile viene recuperata dall'input dell'utente (getRequestString):

Esempio

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Il resto di questo capitolo descrive i potenziali pericoli dell'utilizzo dell'input dell'utente nelle istruzioni SQL.


SQL injection Basato su 1=1 è sempre vero

Guarda di nuovo l'esempio sopra. Lo scopo originale del codice era creare un'istruzione SQL per selezionare un utente, con un determinato ID utente.

Se non c'è nulla che impedisca a un utente di inserire un input "sbagliato", l'utente può inserire un input "intelligente" come questo:

ID utente:

Quindi, l'istruzione SQL sarà simile a questa:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

L'SQL sopra è valido e restituirà TUTTE le righe dalla tabella "Utenti", poiché OR 1=1 è sempre TRUE.

L'esempio sopra sembra pericoloso? Cosa succede se la tabella "Utenti" contiene nomi e password?

L'istruzione SQL sopra è più o meno la stessa di questa:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

Un hacker potrebbe ottenere l'accesso a tutti i nomi utente e le password in un database, semplicemente inserendo 105 OPPURE 1=1 nel campo di input.



SQL injection Basato su ""="" è sempre vero

Ecco un esempio di login utente su un sito web:

Nome utente:

Parola d'ordine:

Esempio

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

Risultato

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

Un hacker potrebbe ottenere l'accesso ai nomi utente e alle password in un database semplicemente inserendo " OR ""=" nella casella di testo del nome utente o della password:

Nome utente:

Parola d'ordine:

Il codice sul server creerà un'istruzione SQL valida come questa:

Risultato

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

L'SQL sopra è valido e restituirà tutte le righe dalla tabella "Utenti", poiché OR ""="" è sempre TRUE.


Iniezione SQL basata su istruzioni SQL in batch 

La maggior parte dei database supporta l'istruzione SQL in batch.

Un batch di istruzioni SQL è un gruppo di due o più istruzioni SQL, separate da punti e virgola.

L'istruzione SQL seguente restituirà tutte le righe della tabella "Utenti", quindi eliminerà la tabella "Fornitori".

Esempio

SELECT * FROM Users; DROP TABLE Suppliers

Guarda il seguente esempio:

Esempio

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

E il seguente input:

ID utente:

L'istruzione SQL valida sarebbe simile a questa:

Risultato

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

Utilizzare i parametri SQL per la protezione

Per proteggere un sito Web dall'iniezione SQL, è possibile utilizzare i parametri SQL.

I parametri SQL sono valori che vengono aggiunti a una query SQL al momento dell'esecuzione, in modo controllato.

Esempio di rasoio ASP.NET

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

Si noti che i parametri sono rappresentati nell'istruzione SQL da un indicatore @.

Il motore SQL controlla ogni parametro per assicurarsi che sia corretto per la sua colonna e che sia trattato letteralmente e non come parte dell'SQL da eseguire.

Un altro esempio

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

Esempi

Gli esempi seguenti mostrano come creare query parametrizzate in alcuni linguaggi Web comuni.

SELEZIONA DICHIARAZIONE IN ASP.NET:

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();

INSERIRE IN RENDICONTO IN ASP.NET:

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();

INSERIRE NELLA DICHIARAZIONE IN PHP:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();