Può verificarsi un attacco di SQL injection se l'input può essere solo caratteri esadecimali?

0

Ho impostato un sistema di accesso che funziona più o meno in questo modo:

1) L'utente inserisce i dati

2) I dati vengono sottoposti a hash localmente usando SHA256 (per ridurre il rischio che qualcuno rubi la password attraverso un uomo nell'attacco centrale e lo usi da qualche altra parte).

3) Gli hash vengono inviati su una connessione sicura al server

4) Una volta arrivati, vengono immediatamente controllati per assicurarsi che non contengano caratteri non validi. Questa è la funzione:

function IsHexadecimal($pass){
    $allowedChars = '0123456789abcdef';
    $passLenght = strlen($pass);
    for($i = (int)0; $i < $passLenght; $i++){
        if(strpos($allowedChars, $pass[$i]) == false && $allowedChars[0] != $pass[$i]){
            return false;
        }
    }

    return true;
}

5) Se sono caratteri esadecimali validi, il processo di autenticazione continua: gli hash vengono combinati con un sale di 64 caratteri generato casualmente assegnato a quell'utente particolare, quindi eseguito di nuovo l'hash con pbkdf2. Infine, questo nuovo hash viene confrontato con quello di un negozio nel database.

Poiché seguo il metodo predefinito per la protezione dagli attacchi SQL injection, evitando l'input, volevo chiedere se un simile attacco potesse essere eseguito contro il sistema che ho configurato.

    
posta AvidScifiReader 23.06.2016 - 12:05
fonte

2 risposte

2

In primo luogo, consiglierei di utilizzare la funzione di sotto, che sarebbe più efficiente e più severa secondo me.

<?php
    function IsHexadecimal($pass)
    {
        return preg_match('/^[0-9a-f]{64}$/i', $pass);
    }

    // or as @martinstoeckli suggested
    function IsHexadecimal($pass)
    {
        return (ctype_xdigit($pass) && strlen($pass) === 64);
    }
?>

Questa funzione restituirà boolean ( TRUE o FALSE ) e corrisponderà a 0-9 , maiuscolo e minuscolo a-f (vedi /i flag) e controlla una lunghezza esatta di 64 caratteri, che attualmente non funziona nella tua funzione.

Inoltre, suggerirei di rinominare la funzione IsHexadecimal in IsSHA256format nel caso in cui si utilizzi il controllo della lunghezza come suggerito nelle due funzioni precedenti.

In secondo luogo, personalmente non ho mai sentito parlare di iniezioni SQL che utilizzano solo esadecimali. Non ritengo questo tecnicamente possibile.

A meno che non ci sia un'altra funzione che sostituisce alcuni dati e che effettivamente crea un'iniezione SQL con un certo ordine di caratteri. Questo è possibile solo quando $pass ha passato la funzione IsHexadecimal (quindi in formato 0-9a-fA-F{64} ) e i dati non sono correttamente disinfettati nella query SQL, ma ciò sembra altamente improbabile.

Inoltre, consiglierei di ripetere l'hash SHA256 lato server (come descritto) ma usando tecniche di stretching e soprattutto salatura. In questo modo, l'hash che viene inviato su TLS sarà diverso da quello archiviato nel database e sarà più difficile da indovinare quando trapelano da quando si utilizza salatura e stretching. Un buon articolo su questo è Hash delle password salate - Farlo bene . Nella tua situazione attuale, la password viene semplicemente sottoposta a hash due volte senza sale. L'hash è ancora abbastanza facile da confrontare con la lista di parole / tabella arcobaleno.

    
risposta data 23.06.2016 - 12:19
fonte
6

No, l'iniezione con solo caratteri esadecimali non è possibile.

Un altro (migliore?) modo per prevenire l'SQL injection è usare dichiarazioni preparate :

$stmt = $mysqli->prepare("SELECT * FROM User WHERE Password=?");
$stmt->bind_param("s", $password);
$stmt->execute();

Poiché lo si lascia al motore del database per inserire correttamente i dati nella query SQL, SQL injection non è possibile. In questo modo non devi preoccuparti se hai eseguito correttamente il escape di tutti i tuoi dati.

    
risposta data 23.06.2016 - 12:25
fonte

Leggi altre domande sui tag