PHP nos presenta un conjunto de funciones que nos permitirán la validación y saneamiento de datos de una forma sencilla. La funcion filter_var (PHP >=5.2) nos permite filtrar una variable según el filtro especificado.
La sintaxis de la función es simple:
mixed filter_var ( mixed $AFiltrar , int $tipo_filtro , mixed $opciones_filtro [opcional] );
La salida será los datos filtrados o false en caso de fallo. Importante es el último parámetro en el que podemos añadir opciones, en formato array asociativo o banderas. Existen diferentes formas de especificar tanto opciones como banderas:
- Para filtros que acepten opciones y banderas. Se pueden pasar en formato array asociativo multidimensional.
$opciones = array(
'options' => array(
'default' => 3, // valor a retornar si el filtro falla
// más opciones aquí
'min_range' => 0
),
'flags' => FILTER_FLAG_ALLOW_OCTAL,
);
O podemos indicar solo opciones en un array asociativo
$op= array('options' =>
array('min_range'=>10, 'max_range' => 20)
);
- Para filtro que únicamente acepten banderas, se pueden introducir directamente
$var = filter_var('oops', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
O podemos pasar en forma de array asociativo
filter_var('oops', FILTER_VALIDATE_BOOLEAN,
array('flags' => FILTER_NULL_ON_FAILURE));
Dependiendo de nuestra implementación, nos interesará filtrar únicamente o sanear. Vamos a ver ejemplos con los filtros más comunes tanto para filtrar como para sanear:
1. Filtrado de booleanos
El filtro FILTER_VALIDATE_BOOLEAN valida el dato pasado como booleano.
A) Posibles valores de retorno.
El valor de retorno será TRUE para "1", "true", "on" y "yes". Devuelve FALSE en caso contrario.
B) Posibles banderas:
- FILTER_NULL_ON_FAILURE: Si se especifica, devolverá FALSE sólo para "0", "false", "off", "no", y "", y NULL para cualquier valor no booleano.
$valor = TRUE;
if(filter_var($valor,FILTER_VALIDATE_BOOLEAN)) {
echo 'Correcto';
} else {
echo 'Error';
}
2. Filtrado de enteros
El filtro FILTER_VALIDATE_INT valida si lo introducido es un entero o no.
A) Posibles opciones:
- min_range: Especifica el mínimo entero permitido.
- max_range: Especifica el máximo entero permitido.
B) Posibles banderas:
- FILTER_FLAG_ALLOW_OCTAL: Permite valores en octal.
- FILTER_FLAG_ALLOW_HEX: Permite valores en hexadecimal.
$valor = '122121';
if(filter_var($valor,FILTER_VALIDATE_INT)) {
echo 'Correcto';
} else {
echo 'Error';
}
$op= array('options' =>
array('min_range'=>10, 'max_range' => 20)
);
if(filter_var($valor, FILTER_VALIDATE_INT, $op) === false){
echo 'Valor incorrecto';
}else{
echo 'Valor correcto';
}
3. Saneamiento de enteros
El filtro FILTER_SANITIZE_NUMBER_INT elimina todos los caracteres excepto dígitos y los signos de suma y resta.
$valor = 'uno23';
echo filter_var($valor, FILTER_SANITIZE_NUMBER_INT);
Con lo que nos devuelve ’23′ debido a que elimina todos los caracteres no numéricos de la cadena.
4. Filtrado de flotantes
El filtro FILTER_VALIDATE_FLOAT valida si el dato pasado es un flotante o no. Por defecto el separador de decimales es el punto.
A) Posibles opciones:
- decimal: Permite especificar el carácter separador de decimales.
B) Posibles banderas:
- FILTER_FLAG_ALLOW_THOUSAND: Permite usar una coma en en separador de miles.
$valor = '1,234';
if(filter_var($valor,FILTER_VALIDATE_FLOAT)) {
echo 'Correcto';
} else {
echo 'Error';
}
En este caso el filtro retornara falso ya que $valor no es un flotante. Tendría que ser '1.234' para ser flotante. Pero podríamos especificar que el separador para el decimal sea ','. Haremos uso de la única opción disponible.
$valor = '1,234';
$op = array('options'=>array('decimal'=>','));
echo filter_var($valor, FILTER_VALIDATE_FLOAT, $op);
5. Saneamiento de flotantes
El filtro FILTER_SANITIZE_NUMBER_FLOAT elimina todos los caracteres a excepción de los dígitos, +- y, opcionalmente, los caracteres '. , e E'.
A) Posibles banderas:
- FILTER_FLAG_ALLOW_FRACTION: Permite usar un punto en el separador de decimales.
- FILTER_FLAG_ALLOW_THOUSAND: Permite usar una coma en en separador de miles.
- FILTER_FLAG_ALLOW_SCIENTIFIC: Permite notación científica con e o E.
$numero="5-2f+3.3pp";
var_dump(filter_var($numero, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
El resultado será:
string(7) "5-2+3.3"
6. Filtrado de emails
El filtro FILTER_VALIDATE_EMAIL valida si el email pasado puede existir, de acuerdo a unas reglas. No verifica su existencia.
$valor = 'test@ejemplo.com';
if(filter_var($valor,FILTER_VALIDATE_EMAIL)) {
echo 'Correcto';
} else {
echo 'Error';
}
7. Saneamiento de emails
El filtro FILTER_SANITIZE_EMAIL elimina todos los caracteres menos letras, dígitos y !#$%&'*+-/=?^_`{|}~@.[].
$var="some(one)@exa\\mple.com";
var_dump(filter_var($var, FILTER_SANITIZE_EMAIL));
string(19) "someone@example.com"
8. Filtrado de una URL
El filtro FILTER_VALIDATE_URL valida si el valor recibido pertenece a una URL valida. No verifica su existencia.
A) Posibles banderas:
- FILTER_FLAG_SCHEME_REQUIRED: Requiere que URL cumpla esquema RFC (http://ejemplo). Por defecto.
- FILTER_FLAG_HOST_REQUIRED: Requiere que la URL tenga el nombre del host (http://www.ejemplo.com). Por defecto.
- FILTER_FLAG_PATH_REQUIRED: Requiere que la URL tenga una ruta tras el nombre del dominio (www.ejemplo.com/test/).
- FILTER_FLAG_QUERY_REQUIRED: Requiere que la URL tenga una 'query string' ("test.php?name=Jose&age=40").
$valor = 'http://www.ejemplo.com';
if(filter_var($valor,FILTER_VALIDATE_URL)) {
echo 'Correcto';
} else {
echo 'Error';
}
$url = "example.php?name=Jose&age=40";
if(!filter_var($url, FILTER_VALIDATE_URL,FILTER_FLAG_QUERY_REQUIRED)){
echo "URL no válida";
}
else
{
echo "URL válida";
}
Cuidado con el uso de este filtro ya que puede haber problemas al validar como correcto posible código XSS.
9. Saneamiento de una URL
El filtro FILTER_SANITIZE_URL elimina todos los caracteres excepto letras, dígitos y $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=.
$var="http://www.ejemploåøs.coøm";
echo filter_var($var, FILTER_SANITIZE_URL);
//Resultado: http://www.ejemplo.com
10. Filtrado de una IP
El filtro FILTER_VALIDATE_IP se encarga de validar si la ip introducida es correcta. No comprueba su existencia.
A) Posibles banderas:
- FILTER_FLAG_IPV4: Requiere que la ip sea un valor IPv4 válido (ej: 192.168.0.12)
- FILTER_FLAG_IPV6: Requiere que la ip sea un valor IPv6 IP válido (ej: 2001:0db8:85a3:08d3:1319:8a2e:0370:7334)
- FILTER_FLAG_NO_PRIV_RANGE: Requiere que la ip no este en los siguientes rango privados IPv4: 10.0.0.0/8, 172.16.0.0/12 y 192.168.0.0/16. Además si la ip es IPv6 no puede empezar por FD o FC.
- FILTER_FLAG_NO_RES_RANGE: Requiere que la ip no este en alguno de los siguientes rangos IPv4 reservados: 0.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24 y224.0.0.0/4. Este flag no se aplica a direcciones IPv6.
$valor = '192.168.0.1';
if(filter_var($value01,FILTER_VALIDATE_IP)) {
echo 'Correcto';
} else {
echo 'Error';
}
$ip = "2001:0db8:85a3:08d3:1319:8a2e:0370:7334";
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) echo "Error";
else echo "correcto";
11. Filtrado de una expresión regular
El filtro FILTER_VALIDATE_REGEXP valida un valor con una expresión regular compatible con Perl.
A) Opciones (obligatoria):
- regexp: Especifica la expresión regular contra la que validaremos el valor pasado.
$email = "test@ejemplo.com";
$patron = "/^\S+@[\w\d.-]{2,}\.[\w]{2,6}$/iU";
if(filter_var($email, FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>$patron))) === false) echo "Fallo";
else echo "Correcto";
12. Saneamiento de textos
El filtro FILTER_SANITIZE_STRING Elimina etiquetas y opcionalmente elimina o codifica caracteres especiales. Por defecto, cualquier carácter no valido en una cadena. Como por ejemplo, los tags de html.
A) Posibles banderas:
- FILTER_FLAG_NO_ENCODE_QUOTES: Si se indica esta opción, las comillas simples (') y las dobles (") no se codificarán.
- FILTER_FLAG_STRIP_LOW: Elimina todos los caracteres con valor ASCII < 32.
- FILTER_FLAG_STRIP_HIGH: Elimina todos los caracteres con valor ASCII >127.
- FILTER_FLAG_ENCODE_LOW: Codifica todos los caracteres con valor ASCII < 32.
- FILTER_FLAG_ENCODE_HIGH: Codifica todos los caracteres con valor ASCII >127.
- FILTER_FLAG_ENCODE_AMP: Codifica ampersands (&) a &
$value = "<script>alert('Cuidado!');</script>";
echo filter_var($value, FILTER_SANITIZE_STRING);
//Resultado: alert('Cuidado!');
Usando el filtro FILTER_SANITIZE_ENCODED conseguimos el mismo resultado pero codificado como si hubiésemos aplicado urlencode(). Si embargo hay que tener en cuenta que no tiene disponible las banderas FILTER_FLAG_NO_ENCODE_QUOTES ni FILTER_FLAG_ENCODE_AMP. Las cuatro restantes si que están disponibles.
13. Saneamiento de caracteres especiales
El filtro FILTER_SANITIZE_SPECIAL_CHARS se encarga de convertir caracteres especiales en entidades HTML. Equivalente a llamar a la función htmlspecialchars().
A) Posibles banderas:
- FILTER_FLAG_STRIP_LOW: Elimina caracteres con código ASCII < 32.
- FILTER_FLAG_STRIP_HIGH: Elimina caracteres con código ASCII > 127.
- FILTER_FLAG_ENCODE_HIGH: Codifica caracteres con código ASCII < 32.
$value = "<script>alert('Cuidado!');</script>";
echo filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
//Resultado(ver código fuente de la página): <script>alert('Cuidado!');</script>)
Entradas relacionadas
Seguridad PHP - Validación y filtrado 2
No hay comentarios:
Publicar un comentario