php - mysql_real_escape_string - mysqli_real_escape_string($ str);
PHP: ¿Es mysql_real_escape_string suficiente para limpiar la entrada del usuario? (10)
¿Qué situaciones?
Para consultas SQL, es genial. (Las declaraciones preparadas son mejores, yo voto PDO por esto) pero la función se escapa muy bien. Para HTML y similares, no es la herramienta para el trabajo: pruebe un htmlspecialchars
genérico o una herramienta más precisa como HTML Purifier .
Para abordar la edición : la única otra capa que puede agregar es la validación de datos, por ejemplo, confirme que si está insertando un número entero en la base de datos y está esperando un entero positivo, devuelve un error al usuario al intentar colocar una número entero negativo En lo que respecta a la integridad de los datos, mysql_real_escape_string
es lo mejor que tiene para escapar (aunque, de nuevo, las declaraciones preparadas son un sistema más limpio que evita el escape por completo).
¿Es mysql_real_escape_string
suficiente para limpiar la entrada del usuario en la mayoría de las situaciones?
::EDITAR::
Estoy pensando principalmente en la prevención de la inyección SQL, pero en última instancia quiero saber si puedo confiar en los datos del usuario después de aplicar mysql_real_escape_string o si debería tomar medidas adicionales para limpiar los datos antes de pasarlos por la aplicación y las bases de datos.
Veo que la limpieza de los caracteres HTML es importante, pero no lo consideraría necesario para confiar en los comentarios del usuario.
T
Hay diferentes tipos de "limpieza".
mysql_real_escape_string es suficiente para los datos de la base de datos, pero seguirá siendo evaluado por el navegador cuando se muestre si es HTML.
Para eliminar HTML de la entrada del usuario, puede usar strip_tags .
Sugeriría que estudie el uso de PDO lugar de las cosas habituales de MySQL, ya que admite declaraciones preparadas al instante, y las que manejan el escape de datos no válidos para usted.
Hay dos formas, una es usar declaraciones preparadas (como se menciona en otras respuestas), pero eso ralentizará su aplicación, porque ahora debe enviar dos solicitudes a la Base de datos, en lugar de una. Si puedes vivir con el rendimiento reducido, entonces ve a por él; Las Declaraciones preparadas hacen que su código sea más atractivo y fácil de tratar.
Si elige usar mysql_real_escape_string, asegúrese de escapar de todas las cadenas que no son de confianza. Una cadena escapada (mysql_real_escape_string) es segura para SQL Injection . Si no escapas de todas las cadenas, entonces no estás seguro. Realmente deberías combinar mysql_real_escape_string con validación de entrada; verificar que una variable que esperas que contenga un número realmente es un número dentro del rango esperado. Recuerde, nunca confíe en el usuario.
La mejor forma de hacerlo sería utilizar Declaraciones preparadas
La respuesta a su pregunta es No. mysql_real_escape_string () no es adecuado para todas las entradas de usuario y mysql_real_escape_string () no detiene todas las inyecciones de sql. addslashes () es otra función popular para usar en php, y tiene el mismo problema.
código vulnerable:
mysql_query("select * from user where id=".mysql_real_escape_string($_GET[id]));
poc explotar:
http://localhost/sql_test.php?id=1 or sleep(500)
El parche es para usar comillas en ID:
mysql_query("select * from user where id=''".mysql_real_escape_string($_GET[id])."''");
Realmente, el mejor enfoque es utilizar consultas parametrizadas que algunas personas ya han señalado. Pdo funciona bien, adodb es otra biblioteca popular para php.
Si usa mysql_real_escape_string, solo debe usarse para la inyección sql y nada más. Las vulnerabilidades dependen en gran medida de cómo se usen los datos. Uno debe aplicar medidas de seguridad función por función. Y sí, XSS es un PROBLEMA MUY GRAVE . No filtrar por html es un grave error que un hacker utilizará para pw3n usted. Por favor, lea el xss faq .
Para la base de datos, sí. También querrá considerar la posibilidad de escanear / codificar datos para la salida.
También debería considerar validar la entrada con respecto a lo que espera que sea.
¿Has considerado usar declaraciones preparadas ? PHP ofrece numerosas formas de interactuar con su base de datos. La mayoría de ellos son mejores que las funciones mysql_ *.
PDO , MDB2 y MySQL Improved deberían ayudarte a comenzar.
Pensé que agregaría que PHP 5.2+ tiene funciones de filtro de entrada que pueden desinfectar las entradas de los usuarios de varias maneras.
Aquí está la entrada manual , así como una publicación en el blog [por Matt Butcher] sobre por qué son geniales.
Puedes probar ambos, como en
function clean_input($instr) {
// Note that PHP performs addslashes() on GET/POST data.
// Avoid double escaping by checking the setting before doing this.
if(get_magic_quotes_gpc()) {
$str = stripslashes($instr);
}
return mysql_real_escape_string(strip_tags(trim($instr)));
}
mysql_real_escape_string()
es útil para prevenir solo ataques de inyección SQL. No lo ayudará a prevenir ataques de scripts cruzados. Para eso, debe usar htmlspecialchars()
justo antes de dar salida a los datos que se recopilaron originalmente de la entrada del usuario.
mysql_real_escape_string
no es suficiente en todas las situaciones, pero definitivamente es un muy buen amigo. La mejor solución es usar declaraciones preparadas
//example from http://php.net/manual/en/pdo.prepared-statements.php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);
// insert one row
$name = ''one'';
$value = 1;
$stmt->execute();
Además, no olvide HTMLPurifier que se puede utilizar para descartar cualquier carácter no válido / sospechoso.
...........
Editar: Basado en los comentarios a continuación, necesito publicar este enlace (debería haberlo hecho antes para disculparme por crear confusión)
mysql_real_escape_string () versus declaraciones preparadas
Citando:
mysql_real_escape_string () propenso al mismo tipo de problemas que afectan a addslashes ().
Chris Shiflett (experto en seguridad)