Limpiar Variables de Formularios con PHP

Iniciado por FFFenix, 15 Agosto 2011, 06:35 AM

0 Miembros y 1 Visitante están viendo este tema.

FFFenix

Buenas Noches, queria saber que opinaban acerca de mi forma de limpiar las variables que entran por POST en una aplicacion web mia, Bueno sin mas les dejo el Codigo:

Adicional a eso, utilizo una Clase que encontre por ahi, InputFilter (http://www.phpclasses.org/package/2189-PHP-Filter-out-unwanted-PHP-javascript-HTML-tags-.html)
function clean($cleans){
$ifilter=new InputFilter();
return htmlentities($ifilter->process(str_ireplace(array('SCRIPT','FUNCTION','IFRAME','DOCUMENT.','GET /','/','\'','RETURN ','HTTP://','.PHP','.HTACCESS','MYSQL_','ALERT','$_POST','$_GET','$_COOKIE','WINDOW.','String.from','javascript:','ONLOAD','ONUNLOAD','ONERROR',"');",'\"',"/'",'\\','<?PHP','LOCATION.','GETURL(',' SRC=','.cookie','<META','<IMG','','DECLARE','VARCHAR','EXEC','HACK','','SELECT','FROM','WHERE','GRANT','CREATE','DATABASE','SHOW','USE','AND','DROP','LIKE','DELETE','INSERT','INTO','UPDATE','SET','USAGE','VALUES','ALTER','FLUSH','MODIFY','JOIN','"',"'",'XSS','UNION','<INPUT','<FORM','%s'),'',trim($cleans))),ENT_QUOTES,'UTF-8');}


Espero su opinion, Gracias desde ya!

Shell Root

#1
Depende de para que estés usando las variables. Mostrar datos, ejecutar consultas, etc...

Además al estar usando la función htmlentities impides la ejecución del código, ya que se convierten en entidades HTML. No se para qué realizas ese filtro para reemplazar palabras reservadas.
Por eso no duermo, por si tras mi ventana hay un cuervo. Cuelgo de hilos sueltos sabiendo que hay veneno en el aire.

FFFenix

La idea era armar una funcion que limpiara todas las interacciones con el usuario, es para usar en aplicaciones webs, desde login, insertar y modificar datos en una base de datos mysql. Para conectar a la base de Datos MySQL se una class PDO.

La idea de filtrar las palabras era como una especie de seguro extra creo, por si habia algun bug evitar que aprovechen a injectarlo de una forma mas sensilla, almenos reemplazando palabras de ese estilo yo creo que costaria un poco mas no?, En la Aplicacion seria no seria algo practico o que se deba usar las palabra que se reemplazan ahi de igual manera.

Que opinas al respecto? Servira como tengo armada esta funcion para impedir posibles ataques XSS e Injecciones?

Shell Root

A ver, si le pones el htmlentities, no se ejecutará ninguna clase de código. Y sería mucho más fácil hacer una expresión regular que elimine todo lo que esté dentro de las etiquetas < y >, en lugar de poner todos los tag HTML.
Por eso no duermo, por si tras mi ventana hay un cuervo. Cuelgo de hilos sueltos sabiendo que hay veneno en el aire.

FFFenix

Gracias por responder tan rapido :P, Esta buena la idea de una Expresion Regular que borre todo lo que esta dentro de los < >, no se me habia ocurrido =P,
pero con respecto a las injecciones no me conviene poner esa especie de "seguro extra", de reemplazar frases especificas que son utilizadas para injecciones? como SELECT, WHERE, FROM ? o es algo que no serviria para nada?

Shell Root

Pues a ver, depende del entorno en que lo estáis manejando. Es decir, supongamos que tengamos la siguiente query, y que podamos agregarle cualquier valor a la variable $_GET['id'],
Código (sql) [Seleccionar]
SELECT id,nombre,apellido FROM usuario WHERE(id = '1'); -- 1 sería igual a la variable $_GET['id']

Entonces para poder inyectar código a nuestra query original, necesitamos de una comilla simple seguido de las sentencias, en caso de poner la comilla, se tomará como string.

CONCLUSIÓN: El parámetro que más importancia tiene para el filtro es la comilla, ya que es que permite la ejecución de la otra query en la query principal.
Por eso no duermo, por si tras mi ventana hay un cuervo. Cuelgo de hilos sueltos sabiendo que hay veneno en el aire.

FFFenix

#6
Muchas Gracias, voy a ver de solucionar mejorar la funcion, cuando la mejoro la posteare denuevo a ver que dicen :P.
Una Consulta adicional quisiera hacer, seria posible vulnerar por ende este archivo por ejemplo? Una Parte del Codigo Fuente, el mismo agrega unos datos a la base de datos.

if(empty($_POST['nart']) or empty($_POST['rem'])){?><META HTTP-EQUIV="REFRESH"
CONTENT="2;URL=<?php echo $url;?>/funciones/add_stock.php"></head>
<body><div align="center" style="margin-top:15px;"><b>Hubo un Error, Dejo campos
en blanco al agregar el Remito.</b><br /><br /></div>
</body></html><?php }else{if($_POST['ings'] or $_POST['outs'] or $_POST['losts']){
$art=clean($_POST['nart']);
$rem=clean($_POST['rem']);
$ings=clean($_POST['ings']);
$outs=clean($_POST['outs']);
$losts=clean($_POST['losts']);
if(!
is_numeric($art) or !is_numeric($rem) or !is_numeric($ings) or !is_numeric($outs) or !is_numeric($losts)){?>

<META HTTP-EQUIV="REFRESH" CONTENT="2;URL=<?php echo $url;?>/funciones/add_stock.php"></head><body>
<div align="center" style="margin-top:15px;"><b>Hubo un Error, No ingreso correctamente el Numero de
Remito/Cantidad de Ingresos, Egresos o Perdidas, Verifique que haya ingreso unicamente Numeros.</b></div></body></html>
<?php }else{$art=encaes($art);
$rem=encaes($rem);
$ings=encaes($ings);
$outs=encaes($outs);
$losts=encaes($losts);
$cmd=$pdo->prepare('SELECT COUNT(*) FROM stock WHERE remit=?');
$cmd->execute(array($rem));
if(
$cmd->fetchColumn()!=0){
?>
<META HTTP-EQUIV="REFRESH" CONTENT="2;URL=<?php echo $url;?>/funciones/add_stock.php"></head><body>
<div align="center" style="margin-top:15px;"><b>Hubo un Error, El N&deg;de Remito ya existe.</b><br /><br /></div>
</body></html><?php }else{$cmd=$pdo->prepare('INSERT INTO stock (art, remit, outs, ings, losts) VALUES (?, ?, ?, ?, ?);');
$cmd->execute(array($art,$rem,$outs,$ings,$losts));
$cmd=$pdo->prepare('SELECT COUNT(*) FROM rstock WHERE art=?');
$cmd->execute(array($art));
if(
$cmd->fetchColumn()!=0){
$cmd=$pdo->prepare('SELECT * FROM rstock WHERE art=? LIMIT 1;');
$cmd->execute(array($art));
$row=$cmd->fetch(PDO::FETCH_ASSOC);
$outs2=desaes($row['outs']);
$ings2=desaes($row['ings']);
$losts2=desaes($row['losts']);
$outs2=$outs2+desaes($outs);
$ings2=$ings2+desaes($ings);
$losts2=$losts2+desaes($losts);
$outs2=encaes($outs2);
$ings2=encaes($ings2);
$losts2=encaes($losts2);
$cmd=$pdo->prepare('UPDATE rstock SET outs=?, ings=?, losts=? where art=? LIMIT 1;');
$cmd->execute(array($outs2,$ings2,$losts2,$art));
}else{
$cmd=$pdo->prepare('INSERT INTO rstock (art, outs, ings, losts) VALUES (?, ?, ?, ?);');
$cmd->execute(array($art,$outs,$ings,$losts));}


Aclaraciones: encaes() = cifra variable en AES desaes() = descifra Variable en AES, la Funcion clean() es la que esta en el post de arriba.

Me encantaria que si alguien tiene tiempo y ganas de revisar el codigo se lo agradeceria, estoy empezando a querer programar aplicaciones con php y mysql y lo ideal es que no fueran vulnerables!

Gracias nuevamente, voy a aprovechar mañana para darme una vuelta por el foro ya que vi que hay varios post interesantes sobre como limpiar variables y varias funciones que algunos usuarios habian posteado y parece que funcionan bien.

Shell Root

A ver, varias cosas antes de empezar con lo de la seguridad.

1. Deberías de identar el código para que sea más legible.
2. Para imprimir sólo una variable en PHP, la manera más simple es hacer, <?= $var; ?>
3. Consulta los if, else, elseif.
4. Para verificar y validar un número entero, podrías usar el método "casting", de la siguiente forma: (int)$var;
5. Sólo por curiosidad, para que conviertes el valor de las variables en AES?
Por eso no duermo, por si tras mi ventana hay un cuervo. Cuelgo de hilos sueltos sabiendo que hay veneno en el aire.

FFFenix

1. Coincido con vos jaja
2. No sabia eso!, no hay problemas de compatibilidad segun versiones o so o algo? y con respecto a la velocidad es mas rapido hacer un echo o llamar a una variable <?php= $var; ?> ?
3. No entendi que me quisiste decir u.U
4. Lo intente hacer pero por algun motivo cuando queria comprobar si eran solo numeros con el int no me lo tomaba y lo deje asi
5. La idea era para que no pudieran recuperar la info, la password de el AES es de 256 Caracteres y esta guardada en una variable en un file, el archivo esta bloqueado con el htaccess. Es mas que nada un gusto eso del AES, si en algun momento quisiera vender algo creo que decir esta cifrado en AES queda copado ajaj.

Shell Root

3. Lo que quise decir es qué puedes hacer esto,
Código (php) [Seleccionar]
if( /*Condición1*/ ){ [...] }elseif( /*Condición2*/ ){ [...] }elseif( /*Condición3*/ ){ [...] }else{ [...] }

en vez de esto,
Código (php) [Seleccionar]
if( /*Condición1*/ ){ [...] }else{ if( /*Condición2*/ ){ [...] } }

5. Al convertir una variable en cualquier algoritmo no evita la inyección de código SQL. Esto lo digo, porque un amigo pensaba que al cifrar la variable id en base64 evitaba esta vulnerabilidad...
Por eso no duermo, por si tras mi ventana hay un cuervo. Cuelgo de hilos sueltos sabiendo que hay veneno en el aire.