Os dejo aquí cinco consejos básicos que debéis seguir en la creación de vuestras aplicaciones para que sean más seguras.
Consejo 1: Utilizad el reporte de errores correctamente.
Durante el proceso de desarrollo de una aplicación el reporte de errores puede llegar a ser vuestro mayor amigo, pero una vez paséis al entorno de producción, es necesario esconder todo tipo de reporte, pues puede facilitar el trabajo a posibles atacantes.
Para modificar el reporte de errores podéis hacerlo desde la configuración de apache, cambiando las lineas:
display_errors = On
display_startup_errors = On
a
display_errors = Off
display_startup_errors = Off
o bien configurarlo directamente en el script de PHP mediante la función:
error_reporting(0)
Consejo 2: Inhabilita las “malas funcionalidades” de PHP
Una de las primeras cosas que deberías hacer cuando empiezas un desarrollo es inhabilitar las siguientes funcionalidades.
Register Globals (register globals)
En un principio esta funcionalidad nos ayuda a hacer aplicación de forma rápida y sencilla, pero en el fondo está permitiendo a un atacante tener acceso total a las variables de entrada de una forma muy sencilla. Por ejemplo:
En la url http://misitio.com?var=1 para acceder a la variable var desde el código simplemente deberíamos escribir $var, y con el register_globals inhabilitado debemos hacerlo mediante $_GET['var'].
Esto supone una medida de seguridad porqué pueden modificar de cualquier modo el valor de la variable $var.
Para inhabilitar el uso de variables globales podemos hacerlo de dos modos. Como en el caso anterior mediante el fichero php.ini modificando la siguiente variable:
register_globals = Off.
O mediante el fichero .htaccess:
php_flag register_globals 0
Magic Quotes
Cuando habilitamos esta opción, todos los caracteres ‘ (comilla sencilla), ” (comilla doble), (barra invertida) y NULL se escapan con una barra invertida de forma automática. Esto es idéntico a lo que hace la función addslashes().
Existen tres directivas de comillas mágicas:
Inhabilitar con el fichero htaccess:
php_flag magic_quotes_gpc 0 php_flag magic_quotes_runtime 0
O mediante el fichero php.ini.
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
Consejo 3: Validación de entradas.
Además de escapar caracteres, otro buen método de proteger las entradas de datos es validándolas. Este consejo simplemente viene a decir es que si estás esperando un tipo de datos solo se permita al usuario introducir ese tipo de datos.
Consejo 4: Evitar Cross-Site-Scripting (XSS) en las entradas del usuario
Una aplicación web usualmente acepta datos de entrada por parte de los usuarios, para posteriormente mostrarlos. Esto obviamente, puede producir, un ataque XSS o Cross-Site-Scripting.
Es posible que un usuario intente introducir código HTML o Java Script a través de nuestros formularios para que a posteriori sea mostrado a terceros. Esto abriría la puerta a ataques hijacking o de robo de cookies.
Hay un par de maneras de proteger tu site de este tipo de ataques. El primero es inhabilitar totalmente la entrada de cualquier tipo de HTML o Java Script, existen funciones que nos permiten realizar estas tareas como pueden ser strip_tags()
Si nuestra aplicación necesita almacenar datos HTML tenemos varias alternativas como transformar los tags en BBCode.
Consejo 5: Evitar SQL Injection
Para terminar pero no por ello menos importante, la prevención de ataques de inyección SQL. Si no se controlan correctamente las entradas de datos por parte del usuario el mismo podría estar introduciendo una cadena de escape seguida de una sentencia SQL a ejecutar.
Por ejemplo si tenemos un formulario de registro donde comprobamos los datos usuario y contraseña de un usuario con la siguiente sentencia:
$sql = "SELECT count(*) cuantos FROM users WHERE user='".$usuario."' AND passowrd='".$password."'";
y dos campos html de entrada de datos uno para el login y otro para el password, si no escapamos datos correctamente, podríamos encontrarnos con un usuario que introdujera los siguientes datos:
user: admin
password ‘ or ‘a’='a
con lo que la sentencia SQL quedaría del siguiente modo:
SELECT count(*) cuantos FROM users WHERE user=’admin’ AND passowrd=” or ‘a’='a’
Con lo que entraría siempre, por este motivo es importante evitar este tipo de cosas.