Работа - > реальный 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>";
}
}
?>
Спасибо.
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(*) ...
, так как это то, что более эффективен для этих целей.