English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Iniezione SQL (Injection)

In questo tutorial, imparerai come correggere le vulnerabilità comuni nei database.

Cos'è l'iniezione SQL?

L'iniezione SQL è un attacco in cui l'aggressore può注入o eseguire codice SQL malizioso nei dati inseriti nel server dell'applicazione tramite il browser (ad esempio, input dei moduli web).

Può essere utilizzato per rendere pubblico informazioni sensibili, come il numero di telefono dell'utente, l'indirizzo email, le informazioni sulla carta di credito, ecc. Gli aggressori possono anche utilizzarlo per aggirare il processo di autenticazione e ottenere l'accesso completo al database. Vediamo come funziona.

Come funziona l'iniezione SQL

Considera la seguente query SQL, che è un esempio semplice di autenticazione degli utenti utilizzando nome utente e password in un'applicazione web.

SELECT * FROM users WHERE username='username_val' AND password='password_val';

qui,username_valepassword_valche rappresentano il nome utente e la password inseriti dall'utente. Se l'utente inserisce valori come “john” come nome utente e “123” come password, la query risultante sarà:

SELECT * FROM users WHERE username='john' AND password='123';

Ma supponiamo che, se l'utente è l'aggressore, non ha inserito un nome utente e una password validi nei campi di input, ma ha inserito valori simili a quelli seguenti: ' OR 'x'='x

In questo caso, la query SQL menzionata sopra sarà costruita come:

SELECT * FROM users WHERE username='' OR 'x'='x' AND password='' OR 'x'='x';

Questa è una query SQL valida, poiché WHERE 'x'='x' è sempre true, quindi la query restituiràuserstutte le righe della tabella. Puoi vedere che l'aggressore può facilmente accedere a tutte le informazioni sensibili del database tramite un piccolo trucco.

seuserstabella molto grande che contiene milioni di righe, questa singola istruzione potrebbe anche causare un attacco di denegazione di servizio (DoS) portando a un sovraccarico delle risorse di sistema e rendendo l'applicazione non disponibile per gli utenti validi.

Attenzione:Se il tuo script genera unaDELETEoUPDATESe esegui una query, ignorare le conseguenze delle vulnerabilità di iniezione SQL può essere ancora peggiore. Gli attaccanti possono eliminare dati dalla tabella o modificare permanentemente tutte le righe.

Prevenzione dell'iniezione SQL

Verifica sempre l'input dell'utente, non farti mai delle supposizioni. Non costruire mai una query SQL direttamente dall'input dell'utente. Se stai utilizzando PHP e MySQL, puoi utilizzare la funzione mysqli_real_escape_string() per creare una stringa SQL legittima che può essere utilizzata in una query SQL.

Questo è un esempio molto semplice di autenticazione utente con PHP e MySQL, che dimostra come prevenire l'iniezione SQL quando si riceve l'input dell'utente.

<?php
// Starting session
session_start();
 
/* Tentativo di connessione al server MySQL. */
   /* Supponiamo che tu stia eseguendo il server MySQL con impostazioni predefinite (l'utente 'root' non ha una password) */
$link = mysqli_connect("localhost", "root", "", "demo");
 
// Verifica la connessione
if($link === false){
    die("Errore: Impossibile connettersi al database.");
}
 
// Evita di eseguire l'iniezione SQL tramite l'elaborazione degli input utente
$username_val = mysqli_real_escape_string($link, $_POST['username']);
$password_val = mysqli_real_escape_string($link, $_POST['password']);
 
if(isset($username_val, $password_val)){
    // Tentativo di selezionare l'esecuzione della query
    $sql = "SELECT * FROM users WHERE username='" . $username_val . "' AND password='" . $password_val . "'";
    if($result = mysqli_query($link, $sql)){
        if(mysqli_num_rows($result) == 1){
            // L'utente è stato autenticato, esegui l'operazione qui
            $row = mysqli_fetch_array($result);
            /*Salva i valori delle variabili di sessione*/
               in modo da poter accedere a essi in seguito nella stessa sessione di riferimento
            $_SESSION['user_id'] = $row['user_id'];
            $_SESSION['first_name'] = $row['first_name'];
            header('Location: welcome.html');
        }
            echo "Errore! Nome utente o password non validi.";
        }
    }
        echo "Errore: è successo qualcosa di sbagliato. Riprova di nuovo.";
    }
}
 
//Chiudi la connessione
mysqli_close($link);
?>

Suggerimento:Testare la dimensione e il tipo o il contenuto dei dati ricevuti dall'applicazione di test, e applicare limiti appropriati per prevenire l'uso delle risorse del sistema.