2010-07-08 18 views
7

Tengo una aplicación que toma datos a través de una solicitud POST. Estoy usando esta información para insertar una nueva fila en la base de datos. Sé que usar mysql_real_escape_string() (más eliminar% y _) es el camino a seguir para las cadenas, pero ¿qué pasa con los valores enteros? En este momento, estoy usando la función PHP intval() en ellos.Sanitizing Integer Database Input

Sin embargo, quería asegurarme de que intval() es perfectamente seguro. No veo la forma en que un atacante realice un ataque de inyección SQL cuando las variables se ejecutan primero a través de intval() (ya que siempre devuelve un número entero), pero quería asegurarme de que este es el caso de personas que tienen más experiencia que yo

Gracias.

+0

Cabezas: Si se trata de números mayores a 32 o 64 bits (según su plataforma) 'intval()' devolverá cero. Esto es obviamente indeseable si está tratando de almacenar números muy grandes en su base de datos. Por ejemplo, los ids de Facebook no se han incluido en 32 bits durante años http://developers.facebook.com/blog/post/45 –

+0

@Frank Farmer: Hm ... eso es interesante. Gracias por el aviso. Voy a ver qué podemos hacer para resolver ese problema, si es necesario. –

Respuesta

21

Sí, intval() es seguro. No hay absolutamente ninguna manera de realizar una inyección SQL cuando el parámetro se convierte a entero, porque (obviamente) el formato de un entero no permite poner palabras clave SQL (o citas, o lo que sea) en él.

+0

Bien, eso es lo que pensé. Gracias. –

+4

También podría usar '(int) $ id' porque la conversión es mucho más rápida que usar la función' intval ($ id) '. Compruebe: http://hakre.wordpress.com/2010/05/13/php-casting-vs-intval/ – DaFrenk

+0

¿Está seguro? Causa intval es muy permisivo en lo que se necesita como un parámetro de entrada. Este código produce resultados enteros correctos, pero nunca me gustaría tener esos valores dentro de mis consultas: '$ var =" 123TYPE_JUGGLING "; var_dump (is_numeric ($ var)); var_dump ((int) $ var); var_dump (intval ($ var)); ' –

4

La forma más fácil de evitar la inyección de SQL es usar siempre declaraciones preparadas. Utilizar las bibliotecas mysqli o mejor aún un ORM como doctrina etc.

Sus consultas se convierten en algo así como:

$stmt = $db->prep_stmt("select * from .... where userid = ? and username = ?"); 

/* Binding 2 parameters. */ 
$stmt->bind_param("is", $userid, $username); 

$userid = 15; 
$username = "don"; 

/* Executing the statement */ 
$stmt->execute() or die ("Could not execute statement"); 
+2

+1 para declaraciones preparadas. Sin embargo, todavía validaría los datos de entrada del usuario antes de ejecutar una inserción para evitar una excepción de SQL. A menos que, por supuesto, el ORM o el marco estuvieran haciendo eso por mí. –

+0

Desafortunadamente, las declaraciones preparadas no están disponibles para este proyecto en particular. –

2

hago siempre

$var = (int)$_POST['var']; 

para asegurarse de que $ var se maneja como un entero en todas las circunstancias, y nunca vuelva a mirar $ _POST ['var']. Mirando el manual, intval() hace exactamente lo mismo.

Cualquiera que sea el camino que tome, en subsequence $ var será un número entero real, que es bastante seguro de manejar.

2

La declaración preparada es la mejor forma de administrar la inyección sql. o use PDO de lo contrario, intval es mejor que is_numeric