Clase PHP para filtrar los parámetros recibidos por GET

2 COMENTARIOS  -  30/07/2010 -  Clasificado en: , , ,

A raiz de la publicación del post The Perishable Press 4G Blacklist me surgió la idea de publicar una de las clases en PHP que utilizo para controlar la seguridad de los sitios web desarrollados en este lenguaje. Toda prevención es poca y hay veces que no tenemos acceso al fichero .htaccess, no conocemos lo suficiente su funcionamiento, el servidor no es Apache, etc. En ese caso utilizar una clase como la siguiente nos puede ser útil para evitar ataques CSRF o XSS mediante parámetros GET.

class dXSS{
	var $url;
	var $longitud;

function TestGet(){
	$ok = true;
	$baneados =array(chr(34),
	"'",
	"--",
	";"
	"<",
	"[",
	"&lt;",
	">",
	"&gt",
	"&quot",
	"&#x27",
	"%",
	"&#x2F",
	"/*",
	"*/",
	"request",
	"select",
	"declare",
	"insert",
	"update",
	"delete",
	"drop",
	"exec(",
	"execute(",
	"cast(",
	"char",
	"nchar",
	"varchar",
	"nvarchar", 
	"substring",
	"sysobject",
	"iframe",
	"syscolumns"
	);
	
	$recuento=0;
	foreach( $_GET as $key => $value ) {
		for($i=0;$i<sizeof($baneados);$i++) {
			$Cadena = strtoupper($value);
			$Encontrar   = strtoupper($baneados[$i]);
			$pos = strpos($Cadena, $Encontrar);
			if($pos !== false) {
			    $recuento++;
			}
			if(strlen($Cadena)>$this->longitud){
			    $recuento++;
			}
			if(eregi('[^a-z0-9_]',$Cadena)){
			    $recuento++;
			}	
		}
	}
		if($recuento>0){
			 header('Location:'.$this->url);
		}
	}
}

La clase testea cada uno de los parámetros recibidos y:
1.- Se asegura que no esté en la lista de palabras baneadas
2.- Se asegura de que no tenga una longitud superior a la especificada
3.- Comprueba que sólo contenga caracteres alfanuméricos
Si se detecta un parámetro no válido se redirige a la $url especificada.

Un ejemplo de funcionamiento sería:

$g = new dXSS();
$g->url = 'http://www.google.es';
$g->longitud = 10;
$g->TestGet();

Este código debe ir antes de que se haya producido cualquier salida desde el navegador. Al principio de la página por ejemplo.

De este modo se aceptarían parámetros como:

http://www.dominio.com/index.php?Id=45&acc=new&op=32

Pero no aceptaría cosas como:

http://www.dominio.com/index.php?p=<script>alert("XSS");</script>

Es bastante interesante definir una longitud pequeña, siempre que sea posible:

$g = new dXSS();
$g->url = 'http://www.google.es';
$g->longitud = 3;
$g->TestGet();

Permitiría:

http://www.dominio.com/index.php?Id=45&sub=3&acc=new&op=32

Pero no:

http://www.dominio.com/index.php?Id=<meta%20http-equiv="refresh"%20content="0;">

o incluso:

http://www.dominio.com/index.php?Id=$%

NOTA: Esta clase únicamente controla los parámetros recibidos por $_GET. Fácilmente se podría adaptar o modificar la clase para la información recibida por $_POST o que incluso se ocupase de ambas cosas pero quería mostrar un uso muy sencillo. Lo ideal es combinar esta clase con otras clases o funciones que comprueben el contenido recibido a través de los formularios, utilizar tokens en los formularios, establecer los permisos apropiados a las carpetas del sitio web, utilizar .htaccess, recurrir a filter_input si la versión de PHP instalada es reciente, etc. En estas cosas más vale que sobre que falte.

Si te ha gustado, puedes compartir este post en...
Posts Relacionados
Comentarios
Comentario realizado el 30/07/2010
daTO
Muy interesante, como siempre. Me anoto la clase
Comentario realizado el 30/07/2010
Erick Ruiz de Chavez
Muy buen comentario, aunque cabe mencionar que es un best practice nunca usar directamente el input de los usuarios en nuestro codigo, es por eso que se dan ataques de Cross Site Scripting (XSS) y SQL Injection.
Deja un comentario

¡Gracias por dejar tu opinión! Por favor procura que tu comentarios sean apropiados respecto al tema tratado en la entrada; que no sean spam, u ofensivos, de otro modo, serán eliminados. Todos los comentarios serán moderados antes de su publicación por lo que su aparición en la web puede verse aplazada un cierto tiempo. Si deseas realizar algún comentario, crítica o sugerencia sobre la propia web puedes hacer a través de la siguiente dirección de correo: webintenta@webintenta.com

Facebook Twitter