Evitar sql injection y xss

Aldrin Gonzalo Martoq Ahumada amartoq en dcc.uchile.cl
Lun Sep 24 19:57:02 CLT 2007


On 9/24/07, Alvaro Herrera <alvherre en alvh.no-ip.org> wrote:
> Ricardo Mun~oz A. escribió:
> >>> $condiciones = array('nombres' => "LIKE %$nombres%", 'otro_campo' => "<>
> >>> $valor", etc.);
> >>> $this->set('clientes', $this->Cliente->findAll($condiciones));
> >>> ...
> > ADOdb para PHP permite hacer lo que mencionas.
> > que tiene de feo el codigo de CakePHP? es solo tu gusto personal o tienes
> > algo concreto que aportar?

Lo que ví lo encontre pésimo. Me explico un poco más abajo.

> El codigo de arriba tiene un SQL injection, no?
> Mi problema con el codigo de arriba es que es un ORM,

El problema con el código que miré de CakePHP es que "no es ni chicha'
ni limona'. No es un ORM, no es una API a base de datos, no es una
framework de templates... es una mezcla de todo eso y parece que mucho
mas.


No hay separación entre los parámetros y el código... para explicarme
mejor, poner sentencias SQL como "LIKE %nombre%" entre los parámetros
es la misma chicha que llamar a algo del estilo:
"where nombre='" + mysql_sanitize("pepe") + "'";



Además, antes de responder fui a ver el link de CakeWalk que
publicaste, encontré cosas del estilo (que cuentan como lo mejor del
mundo):

--- http://www.scribd.com/doc/5546/CakePHP-tutorial-no-3-from-IBM ---
$san = new Sanitize();
$clean = $san->paranoid($your_data, array('_','.'));
NOTE: The paranoid method will strip out any spaces unless you pass '
' as an allowed character in the $allowedChars array.
----------------------

No se si valga la pena comentar todos los problemas que acarrea este
horrible ejemplo ... Así que prefiero separarlos por temas:

1. La transformación de datos es un tema.
2. La validación de datos es otro tema.
3. La persistencia de datos es otro tema.



Si bien, no hay nada de malo en que CakePHP intenta solucionar los 3
problemas, el error que vi en la implementación es que la
especificación mezcla los conceptos, permitiendo el tipo de burradas
como paranoid(). Ejemplos relativos a los temas 1, 2 y 3:

1. The Sanitize html method:
The html method of Sanitize can pass two parameters: the string being
Sanitized and an optional Boolean flag referred to as $remove.

If $remove is set to true, the html method passes the string to the
PHP function strip_tags, which will return the string minus any HTML
tags. For example, strip_tags("<p>Hello</p>", true) will return the
value Hello.

If $remove is false or not set, then the html method replaces some
characters with HTML entities.
Specifically:
          is replaced with &       &
          is replaced with %       %
          is replaced with <       <
          is replaced with >       >
          is replaced with "       "
          is replaced with '       '
          is replaced with (       (
          is replaced with )       )
          is replaced with +       +
          is replaced with -       -
The html method uses preg_replace to perform these replacements

Mi Comentario: Para que "sanitizar" la salida a HTML? Debes usar un
framework de templates o algo similar, no estar declarando qué
convertir y qué no...



2. The Sanitize cleanArray method
[..]
While it would have been easy enough to state "cleanArray walks an
array and cleans each value," it is important to understand what is
being done behind the scenes to **_protect your data_**.

Mi Comentario: Recalco "protect your data". Proteger la data es tema
del negocio, no de una API o Framework. Lo que tu framework debe
asegurarte es que recibes lo que esperas sea desde un formulario web,
desde la red, desde un mensaje MQ o un webservice, etc... La
validación de negocio la haces tu; ejemplos: identificar sesiones y
operaciones válidas, poder realizar un giro siempre que tengas
fondos... *eso es proteger la data*.



3. The Sanitize sql method
The sql method escapes some special characters in a string with
backslashes in order to prepare the string for use in a SQL statement.
Comentario: Igual que en el caso HTML, no tiene sentido proveer de una
API para escapar caracteres para la base de datos... al menos, no
publicarla externamente.


Y bueno, ahí me dió lata seguir leyendo...

-- 
Aldrin Martoq



Más información sobre la lista de distribución Linux