2009-12-01 11 views
5

Mi compañero en un proyecto PHP objeta mi práctica de desinfectar siempre valores enteros en SQL dinámico. Usamos consultas parametrizadas cuando es posible. Pero para las condiciones UPDATE y DELETE, Zend_Db_Adapter requiere una cadena SQL no parametrizada. Es por eso que, incluso sin pensar, siempre escribir algo como:¿Está bien permitir SQL a veces dinámico sin desinfección?

$db->delete('table_foo', 'id = ' . intval($obj->get_id())); 

que es equivalente, pero es una versión más corta (He comprobado el código fuente ZF):

$db->delete('table_foo', $db->qouteInto('id = ?', $obj->get_id(), 'INTEGER')); 

Mi pareja fuertemente objeta esto intval(), diciendo que si el ID $obj es nulo (el objeto aún no está guardado en la base de datos), no notaré un error, y la operación DB simplemente se ejecutará en silencio. Eso es lo que realmente le ha sucedido a él.

Dice que si desinfectamos todas las entradas de formularios HTML, no hay manera de que un ID entero pueda entrar en '; DROP TABLE ...', o ' OR 1 = 1 ', u otro valor desagradable, y se inserte en nuestras consultas SQL. Por lo tanto, estoy paranoico y estoy haciendo nuestras vidas innecesariamente más complicadas. "Deja de confiar en los valores $_SESSION", dice.

Sin embargo, para las condiciones de valores de cadena que está de acuerdo con:

$db->update->(
    'table_foo', 
    $columns, 
    'string_column_bar = ' . $db->qoute($string_value)) 
); 

no pude demostrar que estaba equivocado, y él no pudo probar que estoy equivocado. ¿Puedes hacer algo?

+1

Declaraciones paramétricas! Declaraciones paramétricas! Declaraciones paramétricas! http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php – Cheekysoft

+0

@Cheekysoft Señor, ¿ha leído la pregunta con cuidado? Usamos declaraciones parametrizadas. Envía tu mantra a Zend :) –

+1

¡Guau! Parece que puedes enlazar en eliminar y actualizar: http://stackoverflow.com/questions/1845153/zend-framework-how-to-delete-a-table-row-where-multiple-things-are-true –

Respuesta

7

la que se hace consideran más problemas:

  • tener que localizar a un error que no causa una consulta SQL fallado.
  • Tener que restaurar los datos después de haber cometido un error al desinfectar el formulario y alguien lo explota.

Cualquiera que elija, allí está su respuesta. Personalmente, tiendo a inclinarme hacia el lado paranoico de las cosas también.

En todo caso, podría hacer las dos cosas: crear su propia función que primero comprueba nulo y luego llama a intval(), y usar eso en su lugar. Entonces obtienes lo mejor de ambos mundos.

10

Francamente, su compañero está fuera de su balanceo: desinfectar es barato, no hay una buena razón para no hacerlo. Incluso si está desinfectando lo que está en los formularios HTML, si esos controles de alguna manera interrumpen la producción, le alegrará tener una copia de seguridad en otros lugares. Además, promueve una buena práctica.

Usted debe desinfectar — siempre

0

entrada de formulario debe siempre ser desinfectados IDD, pero no todas las variables que se dedica a una consulta debe ser desinfectado imo ...
El origen de la variable juega un papel importante en este caso .

Sólo hay que saber si los datos utilizados se puede confiar ...

0

Si se mira más profundo dentro del código Zend Framework, se verá que $ db-> quoteInto() se convierte en $ db- > quote que devuelve (string) intval ($ value) con INTEGER como tipo.

Si el tipo no está definido, se llama $ db -> _ quote(). Su código es el siguiente:

protected function _quote($value) 
{ 
    if (is_int($value) || is_float($value)) { 
     return $value; 
    } 
    return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'"; 
} 

Cualquiera que sea el método de llamada utilizado (con o sin especificar el tipo), $ db-> borrar es totalmente seguro.

+0

Doesn ' t importa delete() con quoteInto (... 'INTEGER') silenciosamente traga nulo de todos modos. –

0

Primero debe verificar que la ID no sea nula. Si es así, sabes que no debes hacer una consulta inútil y continuar desde allí. No tiene sentido rastrear problemas leyendo consultas SQL fallidas o más.

3

creo que su pareja está mal - que no está considerando la separación de intereses entre los datos sanatisation en el modelo (donde vive su código DB) y los datos de validación de sus formas.

Normalmente su lógica de validación de formularios estará en un área separada de la aplicación para su modelo. Es decir. al agregar validadores para formar elementos, y por lo tanto esto a menudo se hace en la clase de formulario en sí. El objetivo de esta capa de código de validación es validar la entrada del formulario y devolver los mensajes apropiados si hay algún problema.

Así que creo higienización de datos en el modelo debe ser considerado por separado para esto, ya que el modelo es realmente una clase independiente - y por lo tanto debe ser responsable de su propio higienización de datos. Como en teoría debería poder reutilizar este modelo en otra parte de su aplicación, el modelo no debe suponer que la desinfección se haya realizado en otro lugar, es decir, como parte de la capa de validación del formulario.

El punto principal de su compañero sobre no darse cuenta de las consultas SQL fallidas no es realmente un problema en la práctica; es mejor codificar a la defensiva.

0

Todos los datos recuperados de un formulario deben ser desinfectados. Sin excepciones. Todos los datos recuperados de su sistema ya deberían haber sido desinfectados antes de que entren en su sistema, y ​​por lo tanto no deberían desinfectarse cuando se recuperen del sistema nuevamente.

Entonces, la pregunta es: ¿de dónde viene este número entero?

1

Por supuesto, siempre debe desinfectar y no depender de formularios HTML. ¿Qué pasa si cambias tu código y reutilizas esa parte con algún otro dato, que no proviene del formulario HTML sino del servicio web o el correo electrónico o cualquier otra fuente que decidas agregar un año después? Usar intval() aquí parece estar bien.

Cuestiones relacionadas