Filtrado y Limpieza

Limpiar o desinfectar la entrada del usuario es una parte crítica del desarrollo de software. Confiar o dejar de desinfectar la entrada del usuario podría conducir a un acceso no autorizado al contenido de la aplicación, principalmente datos de los usuarios, o incluso al servidor de la aplicación donde está alojada.

Imagen completa en XKCD

El componente Phalcon\Filter provee un conjunto de filtros y sanitizadores que se utilizan regularmente. Esto provee un envoltorio orientado a objectos sobre la extensión filter de PHP.

Tipos de filtros incorporados

Los siguientes filtros están incorporados en este componente:

Nombre Descripción
absint Clasifica el valor como un número entero y devuelve el valor absoluto del mismo.
alphanum Quita todos los caracteres excepto [a-zA-Z0-9]
email Quita todos los caracteres excepto letras, números y !#$%&*+-/=?^_{\|}[email protected][]`.
float Quita todos los caracteres excepto dígitos, puntos y los signos más y menos.
float! Quite todos los caracteres excepto dígitos, puntos, signos positivo y negativo y convierte el resultado en un float.
int Quita todos los caracteres excepto dígitos y los signos más y menos.
int! Quite todos los caracteres excepto dígitos, signos positivo y negativo y convierte el resultado en un entero.
lower Se aplica la función strtolower
string Elimina etiquetas y codifica entidades HTML, incluyendo comillas simples y dobles.
striptags Se aplica la función strip_tags
trim Se aplica la función trim
upper Se aplica la función strtoupper

Tenga en cuenta que el componente utiliza internamente la función PHP filter_var.

Las constantes están disponibles y pueden utilizarse para definir el tipo de filtrado necesario:

<?php
const FILTER_ABSINT     = "absint";
const FILTER_ALPHANUM   = "alphanum";
const FILTER_EMAIL      = "email";
const FILTER_FLOAT      = "float";
const FILTER_FLOAT_CAST = "float!";
const FILTER_INT        = "int";
const FILTER_INT_CAST   = "int!";
const FILTER_LOWER      = "lower";
const FILTER_STRING     = "string";
const FILTER_STRIPTAGS  = "striptags";
const FILTER_TRIM       = "trim";
const FILTER_UPPER      = "upper";

Limpieza de datos

Es el proceso de desinfección que elimina caracteres específicos de un valor, los cuales no son necesarios o deseados por el usuario o aplicación. Al desinfectar la entrada nos aseguramos que la integridad de las aplicaciones estará intacta.

<?php

use Phalcon\Filter;

$filter = new Filter();

// Retorna '[email protected]'
$filter->sanitize('some(one)@exa\mple.com', 'email');

// Retorna 'hello'
$filter->sanitize('hello<<', 'string');

// Retorna '100019'
$filter->sanitize('!100a019', 'int');

// Retorna '100019.01'
$filter->sanitize('!100a019.01a', 'float');

Limpiando desde controladores

Se puede acceder al objeto Phalcon\Filter desde los controladores cuando se accede a los datos de entrada GET o POST (a través del objeto request). El primer parámetro es el nombre de la variable que se desea obtener; el segundo es el filtro a aplicar sobre ella.

<?php

use Phalcon\Mvc\Controller;

class ProductsController extends Controller
{
    public function indexAction()
    {

    }

    public function saveAction()
    {
        // Limpiando el precio desde POST
        $price = $this->request->getPost('price', 'double');

        // Limpiando el email desde POST
        $email = $this->request->getPost('customerEmail', 'email');
    }
}

Filtrando parámetros de acciones

En el ejemplo siguiente se muestra cómo desinfectar los parámetros de una acción dentro de un controlador:

<?php

use Phalcon\Mvc\Controller;

class ProductsController extends Controller
{
    public function indexAction()
    {

    }

    public function showAction($productId)
    {
        $productId = $this->filter->sanitize($productId, 'int');
    }
}

Filtrando datos

Además de desinfectar, Phalcon\Filter proporciona filtrado, mediante la eliminación o modificación de los datos de entrada llevandolos al formato que esperamos.

<?php

use Phalcon\Filter;

$filter = new Filter();

// Retorna 'Hello'
$filter->sanitize('<h1>Hello</h1>', 'striptags');

// Retorna 'Hello'
$filter->sanitize('  Hello   ', 'trim');

Combinando filtros

Es posible ejecutar varios filtros en una cadena al mismo tiempo, pasando una matriz de identificadores de filtro como segundo parámetro:

<?php

use Phalcon\Filter;

$filter = new Filter();

// Retorna 'Hello'
$filter->sanitize(
    '   <h1> Hello </h1>   ',
    [
        'striptags',
        'trim',
    ]
);

Agregando filtros

Es posible agregar tus propios filtros en Phalcon\Filter. La función de filtro puede ser una función anónima:

<?php

use Phalcon\Filter;

$filter = new Filter();

// Usando una función anónima
$filter->add(
    'md5',
    function ($value) {
        return preg_replace('/[^0-9a-f]/', '', $value);
    }
);

// Desinfectando con el filtro 'md5' recién creado
$filtered = $filter->sanitize($possibleMd5, 'md5');

O si lo prefiere, puede implementar el filtro en una clase:

<?php

use Phalcon\Filter;

class IPv4Filter
{
    public function filter($value)
    {
        return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
    }
}

$filter = new Filter();

// Usando un objeto
$filter->add(
    'ipv4',
    new IPv4Filter()
);

// Limpiando con el filtro 'ipv4'
$filteredIp = $filter->sanitize('127.0.0.1', 'ipv4');

Filtrado y limpieza complejas

PHP ya provee una excelente extensión de filtros. Puedes revisar la documentación: Filtrado de datos en la documentación de PHP

Implementar tus propios filtros

Debe implementar la interfaz Phalcon\FilterInterface para crear su propio servicio de filtrado reemplazando el proporcionado por Phalcon.