vulnerabilidad de inyección SQL cuando se usan declaraciones preparadas en PHP

2

He estado estudiando las declaraciones preparadas y las implementé en mi primer inicio de sesión. Utilicé una declaración preparada para la consulta SQL y me pregunto si esto es suficiente para evitar la mayoría de las inyecciones de SQL.

Dado que la consulta SQL está parametrizada y he escapado del nombre de usuario, creo que debería estar bien. El único problema real que conozco (si hay más, por favor hágamelo saber) es el hecho de que no pude escapar de la entrada de contraseña debido a la forma en que Bcrypt la verifica. Déjame saber si hay una mejor manera de hacer esto.

<!Doctype html>
<html>
<head>
<title>password validation</title></head>
<body>


<fieldset>
<legend>enter password</legend>
<form action =passing.php method = "post">
<table>
<tr>
<td>Email:</td><td><input type="id" name ="id" /><br /></td>
</tr>
<tr>
<td>Password:</td><td><input type = "password" name="password" /><br /></td>
</tr>
</table>
<input type = "submit" name ="submit" value ="insert" />
</form>
</fieldset>
<br />


<?php
// connect to the server

$conn = new mysqli('localhost', 'root', '', 'social');

// check connection
if(mysqli_connect_errno()) {
exit("connection failed" . mysqli_connect_error());
 } else {
 echo "connection established";
 }


if($_POST && isset($_POST['submit'], $_POST['password'], $_POST['id'])) {

$pass = ($_POST["password"]);
$id = mysqli_real_escape_string($conn, $_POST["id"]);
$input = $pass;


$query = mysqli_prepare($conn, "SELECT pass FROM social
 WHERE  email LIKE ?");

mysqli_stmt_bind_param($query,'s', $id );

mysqli_stmt_execute($query);
    mysqli_stmt_bind_result($query, $id);



while(mysqli_stmt_fetch($query)) {

echo "<br />";
echo "SUCCESS at query";

if (password_verify($input, $id)) {
echo "matching pass" . header("Location: inserh.php");
} else{
echo "not a  match";

        }

    }
}

mysqli_close($conn);

// close the connection
    
pregunta nate35795 07.04.2016 - 09:30
fuente

1 respuesta

5

¿Debo escapar de la entrada cuando uso declaraciones preparadas?

No.

Realmente no necesita escapar de la entrada si usa declaraciones preparadas. Si desea una capa adicional de seguridad, use algún tipo de filtro de entrada (p. Ej., Obtener solo números enteros, recibir solo correos electrónicos válidos, solo alfanum, etc.).

Y, obviamente, no debes escapar de tu contraseña, ya que ni siquiera entra en la consulta.

Escapar realmente solo significa que te escapas de ciertos personajes. Esto significa que ' se convierte en \' o \ se convierte en \ . De esa manera, si están dentro de una cadena entre comillas, se interpretan correctamente. Esto puede evitar inyecciones de SQL si la entrada se inserta en una cadena entrecomillada, ya que el atacante no puede salir de esa cadena. No hace nada útil si solo lo aplica a todas las entradas. Y no es necesario si utiliza declaraciones preparadas.

LIKE en lugar de igualdad

No debes usar LIKE si necesitas una coincidencia exacta. El uso de LIKE aquí hace que sea más fácil aplicar fuerza bruta a su inicio de sesión, y facilita la recolección de direcciones de correo electrónico.

Por ejemplo, puedo iniciar sesión correctamente como [email protected]:pass con %@%:pass .

A medida que usa un bucle en lugar de solo obtener un resultado, que es lo que debe hacer, un atacante puede usar %@% como correo electrónico fijo y simplemente forzar las contraseñas.

    
respondido por el tim 07.04.2016 - 11:45
fuente

Lea otras preguntas en las etiquetas