Proyecto integrador. Las TIC en la sociedad S4.pptx
Riesgo y Vulnerabilidades en el Desarrollo
1. Riesgos y Vulnerabilidades
en el Desarrollo Web
Soluciones en PHP (y más)
FIST Conference
Barcelona, 18 de marzo de 2005
Javier Pascual Soriano
javier.pascual@esne.edu
Departamento Tecnologí as de la Informació y las Comunicaciones
n
2. 1. Seguridad y Responsabilidad
¿Quién debe velar por la seguridad?
Administrador del Sistema
• Gestiona los servicios
• Otorga los permisos
Programador de la Aplicación
• Controla la ejecución sobre los
servicios
• Hace uso de los permisos
ESNE – Escuela Superior de Negocios
3. 2. Administración del Sistema
Componentes crí ticos
Servidor Web
• Ej.: Apache
Lenguaje de Programación
• Ej.: PHP
Sistema Gestor de Bases de Datos
• Ej.: MySQL
4. 2.1. Seguridad del Servidor Web
Limitar el acceso a información sensible
• Ocultar la información detallada del servicio:
ServerTokens Prod
ServerSignature Off
• Impedir accesos al sistema de ficheros:
<Directory />
Options –FollowSymLiks -Indexes -ExecCGI
Order Deny,
Allow Deny from all
</Directory>
• Enjaular el servicio (chroot)
Utilizar protocolos seguros para el
servicio y la administración (SSL, SSH,
FTPS, etc.)
5. 2.2. Seguridad del Lenguaje
Elegir el tipo de instalación
• Binario CGI (CERT® Advisory CA-1996-11)
• Módulo de Apache (PHP hereda sus permisos)
Establecer una configuració apropiada (seguridad
n vs usabilidad)
• safe_mode = [On | Off] ; Comprobar UID
• safe_mode_gid = [On | Off] ; Comprobar GID
• safe_mode_exec_dir = “ ” ; Ruta para ejecutables permitidos
• safe_mode_include_dir = “ ” ; Ruta para includes permitidos
• register_globals = [On | Off] ; Convertir a global cualquier parámetro
• safe_mode_allowed_env_vars = PHP_ ; Variables de entorno modificables
• disable_functions, disable_classes = “ ” ; Deshabilitar funciones y clases
• max_execution_time, max_input_time ; Limitar tiempos de procesamiento
• memory_limit, upload_max_filesize, … ; Limitar uso indiscriminado de
recursos
• magic_quotes_gpc, magic_quotes_runtime ; Activar escape automático de params.
• auto_prepend_file, auto_append_file ; Cargar siempre un cierto archivo
6. 2.3. Seguridad del SGBD (I)
Añadir soporte para tablas InnoDB
• Capacidad transaccional
- Permite ejecutar de forma consistente consultas relacionadas
BEGIN WORK, COMMIT, ROLLBACK
- En caso de fallo, completa las transacciones cuando se recupera
• doublewrite
- Técnica de escritura en disco. Permite recuperación ante desastres
• Integridad Referencial
- Permite el uso de claves foráneas en las relaciones entre tablas
• multi-versioning
- Evita conflictos L/E
- Facilita la gestión de bloqueos
7. 2.3. Seguridad del SGBD (II)
Precauciones de accesibilidad
• Impedir conexiones externas: skip-networking
• Evitar el uso de skip-grant-tables en pruebas
• Modificar el usuario root por defecto
• No acceder a la consola usando la
contraseña
mysql –u root –p password
• Cifrar las conexiones mediante SSL
GRANT ALL PRIVILEGES ON bbdd.* TO usuario@“host"
IDENTIFIED BY ‘password' REQUIRE SSL
• Identificar uní vocamente al usuario
GRANT ALL PRIVILEGES ON bbdd.* TO usuario@“host"
IDENTIFIED BY ‘password' REQUIRE [X509|ISSUER|CIPHER]
8. 2.3. Seguridad del SGBD (y III)
Persistencia de la Información
• Consolidación de las tablas a disco
• Automáticamente (incide en el rendimiento)
# mysqld --flush
• Manualmente
1) FLUSH TABLES
2) # mysqladmin flush-tables
• Realizar copias de seguridad periódicas
# mysqldump -a -A -C -F -f --user=backup_user
--password=backup_pass > archivo_seguridad.sql
• Montar servidores de réplica
9. Cosas a tener en cuenta (I)
Todo aquello que asumas que el usuario
nunca hará, será lo primero que haga
cuando entre a tu Sitio Web
10. Cosas a tener en cuenta (II)
Cuando la seguridad se ve comprometida,
la responsabilidad suele recaer sobre el
programador de la aplicación
11. Cosas a tener en cuenta (III)
Nunca asumas que el
Administrador del Sistema
es un tipo competente
12. Cosas a tener en cuenta (y IV)
Si además de programador eres el
Administrador del Sistema …
FELICIDADES!!
YA ERES UN:
¡ ¡ BROWN EATER
!!
13. 3. Seguridad en el Desarrollo Web
1. Definir condiciones de ejecució seguras para las
n
bases de datos.
2. Definir la accesibilidad (ubicació y modo de acceso)
n
al código y las credenciales.
3. Definir cómo se van a procesar los datos de entrada:
canal de entrada, valores por defecto, filtros de
entrada y salida, etc.
4. Definir caracterí sticas crí ticas de la gestió de
n
sesiones.
14. 3.1. Condiciones de las bases datos
Asegurar la integridad transaccional y
referencial con tablas InnoDB.
Hacer borrados lógicos en vez de fí sicos.
Facilitar las posibles operaciones de
reparación:
• Mantener optimizadas las tablas
OPTIMIZE TABLE `nombre_tabla`
• Usar CHAR en vez de VARCHAR
• Intentar separar los campos TEXT y BLOB del
resto de campos mediante tablas enlazadas.
Utilizar usuarios con permisos de sólo lectura
siempre que sea posible.
15. 3.2. Accesibilidad del Código (I)
1) Páginas Independientes (I)
Capa de Seguridad
Capa de Acceso a BBDD
Capa de Código
index.html
pagina1.html pagina2.html pagina3.html
paginaN.html
16. 3.2. Accesibilidad del Código (II)
1) Páginas Independientes (y II)
Ventajas
• Más sencillo (¿lógico?) de programar
• Un fallo no cuelga todo el Sitio Web
Inconvenientes
• Mecanismos de seguridad en cada página
• Más posibilidades de error por descuidos
• Más difí cil de mantener
17. 3.2. Accesibilidad del Código (III)
2) Dispatcher de Archivos (I)
Capa de Seguridad
Capa de Acceso a BBDD
Capa de Código
1) index.php?file=pag1.php
include($file)
2) index.php?file=1
include
(“ pag” .$file.” .php” )
3) Dispatcher de funciones
pagN.php
18. 3.2. Accesibilidad del Código (IV)
2) Dispatcher de Archivos (y II)
Ventajas
• Seguridad centralizada en index.php
• Código ubicado en zonas no accesibles por
HTTP
• Acceso a las variables usadas en index.php
Inconvenientes
• Un fallo en index.php cuelga todo el Sitio
• Se “ pueden” referenciar ficheros de todo el SF
• Pueden producirse accesos desprotegidos
sin pasar por el index.php
19. 3.2. Accesibilidad del Código (V)
2) Dispatcher de Funciones (I)
Capa de Seguridad
Capa de Acceso a BBDD
Capa de Código
1) index.php?opc=1
include(“ opciones.inc.php” );
switch ($opc) {
case 1:
func_opc1
(params);
default:
opciones.inc.php
func_index
(params);
20. 3.2. Accesibilidad del Código (VI)
3) Dispatcher de Funciones (y II)
Ventajas
• Los accesos desprotegidos no producen salida
• No hay posibilidad de referenciar archivos
externos
• Es más sencillo reutilizar el código
Inconvenientes
• Dentro de las funciones no podremos acceder a
las variables no globales
21. 3.2. Accesibilidad del Código (VII)
Protecció de los archivos de inclusió
n n
1) Cargarlos con: include_once(archivo);
2) Siempre acabados en .php: seguridad.inc.php
3) Si puede ser, alojarlos bajo el directorio raí z
4) Asegurar que solo se accede desde index.php
if (!eregi(“index.php”, $_SERVER[“PHP_SELF”])) {
header(“Location: index.php”); exit; }
5) Almacenar las credenciales de acceso a las BBDD
en constantes, nunca en variables:
define(“_DB_USER_”, “cálico”);
define(“_DB_PASS_”, “electrónico”);
22. 3.2. Accesibilidad del Código (VIII)
Otras soluciones “más sofisticadas” (I)
Menos aconsejables, ya que no son responsabilidad exclusiva del programador.
1) Denegar desde Apache el acceso a los .inc:
<Files ~ “.inc$”>
Order allow,deny
Deny from all
</Files>
2) Utilizar archivos .htaccess en la carpeta inc/
- No siempre tenemos posibilidad de
crearlos
- No suelen ser visibles por FTP
23. 3.2. Accesibilidad del Código (IX)
Otras soluciones “más sofisticadas” (II)
3) Tratar los .inc como si fuesen .php
<Directory /var/www/esne.es/httpdocs>
AllowOverride All
Order allow,deny
Allow from all
<IfModule mod_mime.c>
AddType application/x-httpd-php .php
AddType application/x-httpd-php .inc
AddType application/x-httpd-php .php3
AddType application/x-httpd-php .php4
AddType application/x-httpd-php-source .phps
</IfModule>
</Directory>
24. 3.2. Accesibilidad del Código (y X)
Otras soluciones “más sofisticadas” (y III)
4) Guardar las credenciales de acceso a las bases
de datos como variables de entorno en httpd.conf:
SetEnv _DB_USER_ “mejor_php”
SetEnv _DB_PASS_ “que_asp”
Include “/var/www/esne.es/db_users.inc”
$_SERVER[“_DB_USER_”]
Cuidado con:
phpinfo();
print_r($_SERVER);
25. 3.3. Procesamiento de parámetros (I)
Diseñ correcto de los formularios HTML
o
• Método de enví o de datos por POST
• Limitar la longitud de los campos del
formulario: size=“50”
• Nombrar los objetos del formulario de forma
diferente a los campos de la base de
datos.
• No introducir datos sensibles en objetos de
tipo hidden
• Hacer ciertas comprobaciones con
JavaScript:
26. 3.3. Procesamiento de parámetros (II)
Acceder correctamente
1) Utilizar variables súper globales:
$_GLOBALS, $_SERVER, $_GET, $_POST, $_SESSION,
$_COOKIE, $_FILES, $_REQUEST, $_ENV
2) Usar el parámetro en variables inicializadas:
$opc = 1;
3) Evaluar la existencia del parámetro y
asignar:
if (isset($_GET["opc"]))
$opc = $_GET["opc"];
27. 3.3. Procesamiento de parámetros (III)
Evaluar la validez del contenido (I)
4) Evaluar los tipos de datos:
Básicos:
if (IsIntNumber($_GET["opc"]))
$opc = $_GET["opc"];
Complejos:
if (IsEMail($_GET["opc"]))
$opc = $_GET["opc"];
28. Comprobar la validez de un E-Mail
function IsEMail($email)
{
if (strlen($email) < 5 || strlen($email) > 150)
return false;
$email = strtolower($email);
if (ereg('^[a-z0-9]+([.]?[a-z0-9_-]+)*@'.
'[a-z0-9]+([.-]+[a-z0-9]+)*.[a-z]{2,4}$',
$email))
return true;
else
return false;
}
29. Comprobar si el dato es un número entero positivo
function IsIntNumber($Numero)
{
$eregi = eregi_replace("[0-9]+","", $Numero);
if(empty($eregi))
return true;
else
return false;
}
30. 3.3. Procesamiento de parámetros (IV)
Evaluar la validez del contenido (y II)
4) Evaluar longitudes y rangos:
if (strlen($_GET["opc"]) <= 3)
$opc = $_GET["opc"];
if ($_GET["opc"] >= 5 && $_GET["opc"] <= 10)
$opc = $_GET["opc"];
$colores = array(“rojo”, “azul”, “amarillo”);
if (in_array($_GET["opc"], $colores))
$opc = $_GET["opc"];
31. 3.3. Procesamiento de parámetros (V)
Eliminar código “maligno” (I)
5) Prevenir ataques XSS:
htmlentities()
Convierta caracteres a entidades HTML
htmlspecialchars()
Convierte ciertos caracteres a HTML (“ , &,
<, >)
strip_tags()
Elimina cadenas HTML y PHP
preg_replace()
on, <, >, %, ;, script, meta, applet, xml, link,
style, frame, frameset, layer, base, bgsound…
33. 3.3. Procesamiento de parámetros (y VI)
Eliminar código “maligno” (y II)
5) Prevenir SQL y Commands Injections:
• No utilizar mysqli_multi_query(), mysqli_query()
• mysql_escape_string() y mysql_real_escape_string()
Escapan caracteres especiales para usarlos en SQL
• (1)addslashes(),(2)escapeshellcmd() y escapeshellarg()
1. Escapa los caracteres: “ , ‘, y NUL
2. Escapa los comandos y argumentos para usarlos
en la función exec() y similares
• Reforzar activando magic_quotes_gpc
34. Ejemplo. Implementar todas las comprobaciones a la vez antes
de un acceso a BBDD.
// Inicialización
$opc = 1;
// Existencia + Tipo + Rango + Filtros
if (isset($_GET[“opc”]))
if (IsIntNumber($_GET[“opc”])
if ($_GET[“opc”] > 0 && $_GET[“opc”] < 10)
$opc = addslashes($_GET[“opc”]);
// Con total seguridad ;-)
$SQL = “SELECT * FROM opciones WHERE Id = ‘$opc’”;
$rs = mysql_query($SQL);
if (!$rs || mysql_num_rows($rs) <= 0) ……
35. 3.4. Gestión de Sesiones (I)
Caducidad y Cacheo de páginas
PHP
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache"); // HTTP/1.0
HTML
<meta http-equiv="Expires" content="Mon, 26 Jul 1997 05:00:00 GMT">
<meta http-equiv="Last-Modified" content="Sun, 25 Jul 2004 16:12:09 GMT“>
<meta http-equiv="Cache-Control" content=“no-store, no-cache, must-revalidate">
<meta http-equiv="Pragma" content="nocache">
36. 3.4. Gestión de Sesiones (II)
Implementar un sistema de timelimit:
define(“_MAX_TIME”, 600); // 10 minutos
if ($_SESSION[“LastRefresh”] + _MAX_TIME < time())
{
session_unset();
session_destroy();
header(“Location: index.php”);
exit;
}
$_SESSION[“LastRefresh”] = time();
37. 3.4. Gestión de Sesiones (III)
Ataques tí picos usando el ID de sesión:
Cross-Site Request Forgeries
Session Fixation
Session Hijacking
38. 3.4. Gestión de Sesiones (IV)
Fortificar el ID de sesió (I)
n
1) Cambiar valores por defecto de en php.ini:
[session]
session.save_path = “ /tmp” ; Ej.: /var/www/sess
session.name = PHPSESSID ; Ej.: MY_SESSID
session.gc_probability = 1 ; ponerlo a 50
(50%)
session.gc_divisor = 100
session.gc_maxlifetime = 1440 ; ponerlo a 600 (seg.)
session.cookie_lifetime = 0 ; siempre a 0
session.use_trans_sid = 0 ; siempre a 0
session.cache_expire = 180 ; ponerlo a 10 (min.)
session.hash_function = 0 ; ponerlo a 1
39. 3.4. Gestión de Sesiones (V)
Fortificar el ID de sesió (II)
n
2) Regenerar el ID se sesió perió
n dicamente:
Previene los ataques de predicció y fuerza bruta.
n
Reduce el tiempo de vida de ID´ s de sesió robados.
n
Hacerlo, al menos, al comenzar la sesió n.
A regenerar el ID, no se pierde la informació de la sesió
n n.
session_regenerate_id();
40. 3.4. Gestión de Sesiones (VI)
Fortificar el ID de sesió (y III)
n
3) Utilizar técnicas de fingerprinting
Las sesiones que ú nicamente usan session_start() son
vulnerables: predicció fuerza bruta, secuestro, etc.
n,
Más complejidad menos predicció
n más seguridad.
Introducimos “firmas” aleatorias en los formularios.
Comprobamos la validez de la firma antes de procesar los
datos del formulario.
41. 3.4. Gestión de Sesiones (VII)
session_start(); fingerprinting
if (!isset($_SESSION[‘sesion_iniciada'])) {
session_regenerate_id(); // Ejemplo de regeneració de ID
n
$_SESSION[‘sesion_iniciada'] = true;
if (isset($_POST[“token”] && $_POST[‘token'] == $_SESSION['token']) {
// Procesar el formulario …
}
}
$token = md5(uniqid(rand(), true));
$_SESSION['token'] = $token;
…
<form method="POST">
<input type="hidden" name="token" value="<?php echo $token; ?>">
<input type="text" name="message">
</form>
42. 3.4. Gestión de Sesiones (y VII)
Proteger las variables de sesión:
1) Evitar servidores compartidos
- En su defecto, limitar el acceso a /tmp usando safe_mode
2) Almacenar las variables de sesió en BBDD,
n
reescribiendo el manejador de las variables de sesión:
session_set_save_handler ( ‘open’, ‘close’, ‘read’, ‘write’, ‘destroy’, ‘clean’);
function open() { // conectar con la BBDD }
function close() { // cerrar la conexió }
n
function read() { // select para recuperar variables }
function write() { // replace para almacenar variables }
function destroy() { // delete para eliminar variables }
function clean() { // delete para eliminar variables antiguas}
43. 4. Enlaces de interés
Este documento
http://www.esne.es/eventos.php?id=1
http://www.fistconferences.org/archivos.php
Documentació oficial de PHP sobre seguridad
n
http://www.php.net/manual/es/security.php
Chris Shiflett PHP Security Guide
http://www.shiflett.org/php-security.pdf
PHP Security Consortium
http://www.phpsec.org
XSS Prevention
http://blog.bitflux.ch/wiki/XSS_Prevention
PHP Cryptography
http://www.phpmag.net/itr/online_artikel/psecom,id,667,nodeid,114.html
Authentication and Session Management on the Web
http://www.westpoint.ltd.uk/advisories/Paul_Johnston_GSEC.pdf
FAQ sobre sesiones:
http://www.webtaller.com/construccion/lenguajes/php/lessons/sesiones.php
45. Riesgos y Vulnerabilidades
en el Desarrollo Web
Soluciones en PHP (y más)
FIST Conference
Barcelona, 18 de marzo de 2005
Javier Pascual Soriano
javier.pascual@esne.edu
Departamento Tecnologí as de la Informació y las Comunicaciones
n