Proteger código PHP

Julio 2017

Independientemente de la seguridad del sistema operativo del servidor, del servidor HTTP en si mismo y de las opciones de configuración de PHP (php.ini), es necesario pensar en proteger los datos recibidos de los usuarios (a través de formularios o URLs), ya que por lo general es de aquí que provienen la mayor parte de ataques a los servidores web.

Esta protección preventiva se puede clasificar en tres grandes categorías:


Validar los datos ingresados por los usuarios


Cuando una página web permite que los usuarios ingresen y envíen datos a través de formularios, no es suficiente indicarles el formato en que estos deben ser ingresados (correo electrónico, número de teléfono, cantidad de productos), sino que también hay que controlar por el lado del servidor (por ejemplo en PHP) si los datos están conforme al formato establecido. O por ejemplo en el caso de que los números ingresados por el usuario deban ser enteros, bastará con convertir estos en enteros:

<? $numero_de_articulos = intval($_REQUEST['numero_de_articulos']); ?>

Validar los datos enviados a través de URL o formularios


En muchos casos, los datos son enviados de una página a otra a través de una URL (método GET) o a través de un formulario (método GET o (método POST) que el Webmaster ha implementado. Por ello no es raro que una URL termine en un parámetro que designe la sección que se mostrará, como en el siguiente ejemplo:

/index.php?rub=25

Se supone que los usuarios no tienen que modificar este parámetro manualmente, sin embargo es mejor tener en cuenta que esto es posible. Qué pasaría si un usuario modifica la URL de una de las siguientes maneras:

/index.php?rub=0
/index.php?rub=
/index.php?rub=aaaaAAAAAaaaa
/index.php?rub=1+or+1

Cualquiera que sea el tipo de dato enviado a través de la URL o formulario, es indispensable verificar que su formato es el correcto.

Para ello, podemos utilizar la función filter_input().
Veamos un ejemplo, supongamos que un usuario nos ha enviado un correo electrónico a través de un formulario tipo post. El campo se llama “email”. Para obtenerlo debemos hacer lo siguiente:

 $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if($email){
    //El correo electrónico ingresado tiene un formato de correo electrónico correcto
}

Utilizando esta función podemos filtrar muchas cosas: las direcciones IP, las URL. También podemos hacer modificaciones como por ejemplo codificar una cadena que va a ser enviada a través de una URL, como lo haría htmlentities(). Varios filtros pueden ser combinados utilizando el operador bit a bit "|".
Ejemplo para validar una IP enviada a través de una URL, sólo si es que está en el formato ipv4:

$ip = filter_input(INPUT_GET, 'ip', FILTER_VALIDATE_IP | FILTER_FLAG_IPV4);

En el siguiente enlace podrás encontrar todos lo filtros que puedes utilizar.

Nota: Si necesitas aplicar directamente un filtro a una variable, puedes utilizar filter_var().

Proteger el contenido mostrado o enviado por URL


Cuando los datos ingresados por el usuario aparecen en pantalla, es posible que esté contenga código HTML o JavaScript, ésta es la razón por la que hay que proteger los datos ingresados por el usuario:
Si los datos serán vistos en HTML: es necesario codificarlos antes de que sean vistos, o sea convertir todos los caracteres especiales a sus entidades HTML correspondientes. En PHP hay una función que permite automatizar este proceso:

echo htmlentities($_REQUEST[“datos”]);

Si los datos serán mostrados en una URL: será necesario codificar los datos antes de enviarlos como parámetros de la URL. PHP tiene dos funciones que permiten hacer esto: urlencode() y rawurlencode(). La diferencia entre estas dos funciones está en la codificación del espacio, en el primer caso da %20 y en el segundo “+”.

echo 'http://www.misitio?valor='.urlencode($_REQUEST['valor']);

Si los datos serán guardados en una base de datos: es necesario proteger todos los caracteres que tengan una función específica en el servidor de base de datos utilizado. En el caso de PHP y MySQL, la función mysql_escape_string() transforma todos los caracteres que puedan ser nocivos que están contenidos en la cadena de caracteres pasados como parámetros.

$query = 'SELECT id FROM matable WHERE user=”'.mysql_escape_string($_REQUEST['user']).'”';

Si el servidor PHP está configurado con la opción magic_quotes, los datos enviados por los usuarios son protegidos automáticamente con diagonales invertidas (antislash). Por ello antes de protegerlos con mysql_escape_string, es necesario “eliminar” esta protección:

$query = 'SELECT id FROM matable WHERE user=”'.
stripslashes(mysql_escape_string($_REQUEST['user'])).'”';

Ver también


Consulta también

Publicado por Carlos-vialfa. Última actualización: 27 de octubre de 2008 a las 22:42 por Carlos-vialfa.
El documento «Proteger código PHP» se encuentra disponible bajo una licencia Creative Commons. Puedes copiarlo o modificarlo libremente. No olvides citar a CCM (es.ccm.net) como tu fuente de información.