Работа - > реальный escape string


у меня есть логин, который, когда я вставляю имя пользователя и пароль в форму и нажимаю "Enter", и у меня установлено соединение с базой данных, он использует следующую строку кода:

$pass = $mysqli->real_escape_string($_POST['txtpass']);

я информирую себя через интернет, но я не понимаю->real_escape_string

¿что это значит? как он защищает меня от SQL-INJECTION?

я оставляю вам полный кусок кода

 <?php
if(isset($_POST['txtpass'])) 
{
    session_start();
    //variable de conexion: recibe dirección del host , usuario, contraseña y el nombre base de datos
    $mysqli = new mysqli("localhost", "root", "", "bdpersona") or die ("Error de conexion porque: ".$mysqli->connect_errno);
    // comprobar la conexión 
    if (mysqli_connect_errno()) 
    {
        printf("Falló la conexión: %s\n", mysqli_connect_error());
        exit();
    }

    $login = $mysqli->real_escape_string($_POST['txtlogin']);   
    $pass = $mysqli->real_escape_string($_POST['txtpass']);

    $resultado = $mysqli->query("SELECT * FROM tbusuario where login='$login' and pass='$pass' and activo!=0");
    $valida=$resultado->num_rows;
    if($valida != 0)
    {
        $datosUsu = $resultado->fetch_row();
        $_SESSION['nombreusu'] = $datosUsu[3];
        $_SESSION['perfil'] = $datosUsu[4];             
        echo "<META HTTP-EQUIV='Refresh' CONTENT='0; URL=listar.php'>";
    }
    else
    {
        echo 
        "<script> 
            var textnode = document.createTextNode('Usuario ó Password Incorrecto');
            document.getElementById('msg').appendChild(textnode);
        </script>";

    }   
}

?>

Спасибо.

 2
Author: Vidal, 2018-03-29

1 answers

Во многих случаях real_escape_string не защищает вас от SQL-инъекции, потому что есть значения подстановки, которые эта функция не избегает (см. этот вопрос и его ответ).

Если вы хотите защитить себя от SQL-инъекций, используйте подготовленные запросы.

Это очень просто сделать. Прочитайте комментарии в коде, где я объясняю, что я сделал:

 $login = $_POST['txtlogin'];  
 $pass  = $_POST['txtpass'];
/*
  * 1. Usamos prepare en lugar de query
  * 2. Cambiamos las variables por marcadores de posición ?
  *    Este es el núcleo del riesgo de inyección, porque las variables
  *    pueden ser concatenadas con código malicioso que se ejecutaría
  *    Nótese que he puesto las columnas explícitamente en el SELECT
  *    asumiendo que las mismas se llaman nombreusu y perfil ...
*/

$sql = "SELECT nombreusu, perfil FROM  registros where login=? and pass=? and activo!=0";
$stmt = $mysqli->prepare($sql);

/*
  * 3. Pasar parámetros separados  de la instrucción SQL
  *    Así se neutraliza la Inyección
  *    Para ello se usa un método llamado bind_param
  *    Las dos "ss" indican que hay dos columnas en la instrucción SQL de más arriba
  *    y que las mismas son del tipo String, por eso la s. 
  *    Si fueran números sería un i
  *    Luego se pasa el valor de esas variables, las cuales almacenamos desde el POST
  *    Es decir, tiene que haber tantos tipos de datos (en este caso "ss") 
  *    como columnas con marcadores de posición, 
  *    si por ejemplo la 1ª fuera String y la 2ª fuera número, entonces sería "si"
  *    y también tantas variables como columnas (dos variables en este caso)
  *    y tienen que ir en el orden en que aparecen en la consulta
*/
$stmt->bind_param("ss", $login,$pass);
$stmt->execute();

/*
  * 4. Usamos bind_result para almacenar en variables cada columna del SELECT
  *    Esto hay que hacerlo siempre ANTES de fetch...
  *    En bind_result debe habar tantas variables como columnas tenga el SELECT
  *    Nótese que store_result y num_rows ya no son necesarios, porque
  *    dado que fetch devolverá NULL si no hay datos, podemos aprovechar
  *    ese resultado para evaluar, optimizando así el código
*/

 $stmt->bind_result($nombreusu, $perfil);

if ($stmt->fetch())
{
    /* Aquí usaremos las variables de bind_result*/

    $_SESSION['nombreusu'] = $nombreusu;
    $_SESSION['perfil'] = $perfil;             
    echo "<META HTTP-EQUIV='Refresh' CONTENT='0; URL=listar.php'>";
}
else
{
    echo 
    "<script> 
        var textnode = document.createTextNode('Usuario ó Password Incorrecto');
        document.getElementById('msg').appendChild(textnode);
    </script>";

} 

P. D: поскольку, по-видимому, это только проверка, я изменил SELECT * на SELECT COUNT(*) ..., так как это то, что более эффективен для этих целей.

 4
Author: A. Cedano, 2018-03-29 17:15:19