¿Puede ocurrir un ataque de inyección SQL si la entrada solo puede tener caracteres hexadecimales?

0

He configurado un sistema de inicio de sesión que funciona más o menos así:

1) El usuario ingresa los datos

2) Los datos se hash localmente utilizando SHA256 (para reducir el riesgo de que alguien robe la contraseña a través de un hombre en el ataque central y la use en otro lugar).

3) Los hashes se envían a través de una conexión segura al servidor

4) Una vez que llegan, se revisan de inmediato para asegurarse de que no contienen caracteres no válidos. Esta es la función:

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) Si son caracteres hexadecimales válidos, el proceso de autenticación continúa: los hashes se combinan con una sal de 64 caracteres de forma aleatoria asignada a ese usuario en particular, luego se vuelve a escribir mediante pbkdf2. Por último, este nuevo hash se compara con la única tienda en la base de datos.

Ya que estoy siguiendo el método predeterminado para protegerme contra los ataques de inyección de SQL, escapándome de la entrada, quería preguntar si tal ataque podría llevarse a cabo contra el sistema que he configurado.

    
pregunta AvidScifiReader 23.06.2016 - 12:05
fuente

2 respuestas

2

En primer lugar, recomendaría usar la siguiente función, que sería más eficiente y más estricta en mi opinión.

<?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);
    }
?>

Esta función devolverá boolean ( TRUE o FALSE ) y coincidirá con 0-9 , mayúsculas y minúsculas a-f (ver /i flag) y verifica la longitud exacta de 64 caracteres, que su función actualmente no lo hace.

También sugeriría cambiar el nombre de la función IsHexadecimal a IsSHA256format en caso de que use la verificación de longitud como se sugiere en las dos funciones anteriores.

En segundo lugar, personalmente nunca he oído hablar de inyecciones SQL que usen hexadecimales solamente. No considero que esto sea técnicamente posible.

A menos que haya otra función que reemplace algunos datos y que realmente cree una inyección SQL con un cierto orden de caracteres. Esto solo es posible cuando $pass pasó la función IsHexadecimal (por lo tanto, en el formato 0-9a-fA-F{64} ) y los datos no están correctamente desinfectados en la consulta SQL, pero parece muy poco probable.

También, recomiendo volver a lavar el hash SHA256 del lado del servidor (como usted describió) pero usando técnicas de estiramiento y especialmente de salazón. De esta manera, el hash que se envía a través de TLS será diferente del que está almacenado en la base de datos y será más difícil de adivinar cuando se filtró ya que usó sal y estiramiento. Un buen artículo sobre esto es Hashing de contraseña con sal: hacer las cosas bien . En su situación actual, la contraseña se procesa dos veces sin sal. El hash todavía es bastante fácil de comparar con la tabla de lista de palabras / arco iris.

    
respondido por el Bob Ortiz 23.06.2016 - 12:19
fuente
6

No, la inyección con solo caracteres hexadecimales no es posible.

Otra (¿mejor?) manera de prevenir la inyección de SQL es usar declaraciones preparadas :

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

Debido a que lo deja en el motor de la base de datos para colocar correctamente sus datos en la consulta SQL, no es posible la inyección de SQL. De esta manera, no tiene que preocuparse por si ha escapado todos sus datos correctamente.

    
respondido por el Sjoerd 23.06.2016 - 12:25
fuente

Lea otras preguntas en las etiquetas