Categories
PHP Seguridad XSS

XSS o SQL Injection

Una pregunta hecha en un foro:

hola gente

normalmente mis sitios php incluyen en el index (el cual incluye las secciones) el siguiente codigo:

php:

foreach($_REQUEST as $nombre_campo => $valor){
   $asignacion = "$" . $nombre_campo . "='" . $valor . "';";
   eval($asignacion);
}

no hace mas que capturar todo el $_REQUEST y transformarlo en variables comunes.

intentando evitar ataques via XSS o SQL injection es el unico codigo que me resta por analizar, pero no logro llegar a la conclusion de si es o no peligroso o deberia escribir todas y cada una de las variables.

ustedes que opinan?

14 replies on “XSS o SQL Injection”

Pues a mi de primeras me parece una técnica peligrosa. Es similar al funcionamiento de la opción register_globals a 'On', que fue desactivada por defecto en la configuración de PHP hace ya bastante tiempo. El problema principal que tiene es que un usuario tiene libertad de "crear" variables dentro de tu programa, o incluso "machacar" alguna que ya exista, por lo que es un fuente potencial de errores y de problemas de seguridad.

Yo lo que hago es coger siempre en cada programa las variables que espera como entrada a partir de $_GET o $_POST, según sea el caso, efectuando a continuación las comprobaciones necesarias para impedir la introducción de datos no válidos.

Desde luego, es más costoso que lo que propones, pero es un coste que creo que hay que asumir.

Pues yo me pregunto porque quiere convertir en variables "individuales" los contenidos de $_REQUEST si este de por si es una matriz asociativa, y le permite acceder comodamente a los datos, con solo usar como clave, el nombre de lo que seria la variable.

A mi entender convirtiendo los contenidos de la matriz asociativa en variables individuales esta eliminando una de sus facilidades de uso, a la vez que pasa posibles datos "desconocidos" por un EVAL.

Si el llama a su programa con algo como por ejemplo:

http://eldominio.com/programa.php?articulo=34

Accede a ello (al valor 34 en este ejemplo) con $otravariable=$_REQUEST['articulo']

No le veo la ventaja a generar variables individuales y terminar usando $otravariable=$articulo

Otra cosa es recorrer la matriz asociativa $_REQUEST y filtrar cada valor para evitar sorpresas, o simplemente usar (por poner otro ejemplo) un switch que solo procese determinadas ordenes/valores recibidos por $_REQUEST y asi ignorar directamente el resto.

Pero yo nunca pasaria por un EVAL datos llegados de "fuera".

No, se, que opinais ?

To Daniel:

Pues si, estoy de acuerdo contigo. No tienen ningún sentido serializar todas las variables en vez de utilizar las que te interesen en cada página.

¿Que más da escribir $variable que $_REQUEST['variable']?

De todas formas, a mi personalemente me gusta más utilizar $_GET, $_POST & $_COOKIE. El código queda más limpio 🙂

Como ya han mencionado, esa porción de código es innecesaria y puede acarrear problemas de seguridad, tal como comenta Daniel, usar eval sobre datos -sin validar- que llegan desde fuera es muy peligroso, porque permitiría que se pueda ejecutar código PHP arbitrario.

Gente, creo que están minimizando el tema... ese fragmento de código es simplemente PELIGROSÍSIMO. Un riesgo gigante! ... además de innecesario. Y en su lugar trataría las variables sólo aceptando las requeridas, postprocesándolas y recién ahi usándolas.

intente localmente hacer una inyeccion al codigo mencionado pero no pude

podrian mostrarme un ejemplo?

por otro lado es mas eficiente en tiempo de ejecucion

$asignacion="";
foreach($_REQUEST as $nombre_campo => $valor){
$asignacion .= "$" . $nombre_campo . "='" . $valor . "';";
}
eval($asignacion);

mash

Miguel, es similar a lo que se hace con SQL Injection, prueba con:

code:

http://dominio.com/vulnerable.php?demo=x'; die(file_get_contents($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SCRIPT_NAME"]));'

Es un códido EXTREMADAMENTE PELIGROSO que permite ejecutar cualquier instruccion PHP en el servidor.

Utilizando un $nombre_campo con el valor: x=1;CODIGO;$y=
Donde CODIGO puede ser cualquier codigo PHP arbitrario

Ejemplo:

Para ejecutar el comando: system("ls /") basta con filtrarlo con urlencode(): urlencode('x=1;system("ls /");$y=') y el valor resultante utilizarlo en una URL:


http://www.example.com?foo.php?x%3D1%3Bsystem%28%22ls+%2F%22%29%3B%24y%3D=1

Nunca ejecuten comandos como eval(), system() o include() con datos proporcionados por los usuarios.

Con extract() estamos igual, fijaros que dice el manual de PHP referente a extract():

No use extract() en datos no confiables, como entradas de usuario ($_GET, ...).

Ademas, insisto, que razón de peso existiria para tener que convertir una matriz asociativa como es $_REQUEST, en variables individuales ?.

$_REQUEST viene creada por defecto por el interprete de PHP, y es automaticamente global para todas las funciones. Yo creo que visto todo esto, otro de los problemas de este codigo de ejemplo es que la persona que lo creo, no conocia (o no comprendia) el concepto y las enormes posibilidades de las matrices asociativas. Aunque esto es facilmente remediable.

entiendo lo que dicen en los comentarios, pero tome el codigo y me propuse pasarlo y no lo he logrado.

en que forma es TAN peligroso como dicen?

Lo mejor es hacerse una función, comprobar_input() o algo similar, a la que le pasas $_REQUEST y un array con las variables que quieres utilizar en tu script, indicando para cada una de ellas el nombre, el tipo (mira settype() en el manual de PHP) y opcionalmente un valor por defecto.

Intenta no utilizar eval(), ni para datos proporcionados por el usuario ni para nada. Igualmente, no utilices la construcción $$variable ni las funciones system(), exec() y compañía. Si lo estás haciendo, replantéate el código, pensando que esas funciones no existen y que te las tienes que trabajar tú mismo. Es duro, pero vale la pena.

creo q seria bueno ademas de indagar en la seguridad de los codigos, ofrecer aun mas información de como generar codigos mas seguros (más no invulnerables), pienso que al desarrollar bajo plataformas web existen muchas situaciones que hay que tomar encuenta... la solución??

Comments are closed.