Riesgo y Vulnerabilidades en el Desarrollo

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 [email protected] Departamento Tecnologí as de la Información y las Comunicaciones

description

 

Transcript of Riesgo y Vulnerabilidades en el Desarrollo

Page 1: Riesgo y Vulnerabilidades en el Desarrollo

Riesgos y Vulnerabilidades en el Desarrollo Web

Soluciones en PHP (y más)

FIST ConferenceBarcelona, 18 de marzo de 2005

Javier Pascual [email protected]

Departamento Tecnologías de la Información y las Comunicaciones

Page 2: Riesgo y Vulnerabilidades en el Desarrollo

ESNE – Escuela Superior de Negocios

Administrador del Sistema

• Gestiona los servicios

• Otorga los permisos

1. Seguridad y Responsabilidad

Programador de la Aplicación

• Controla la ejecución sobre los servicios

• Hace uso de los permisos

¿Quién debe velar por la seguridad?

Javier Pascual Soriano, [email protected]

Page 3: Riesgo y Vulnerabilidades en el Desarrollo

Servidor Web

• Ej.: Apache

2. Administración del Sistema

Lenguaje de Programación

• Ej.: PHP

Sistema Gestor de Bases de Datos

• Ej.: MySQL

Componentes crí ticos

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 4: Riesgo y Vulnerabilidades en el Desarrollo

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.)

2.1. Seguridad del Servidor Web

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 5: Riesgo y Vulnerabilidades en el Desarrollo

Elegir el tipo de instalación

• Binario CGI (CERT® Advisory CA-1996-11)

• Módulo de Apache (PHP hereda sus permisos)

Establecer una configuración apropiada (seguridad 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

2.2. Seguridad del Lenguaje

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 6: Riesgo y Vulnerabilidades en el Desarrollo

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

2.3. Seguridad del SGBD (I)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 7: Riesgo y Vulnerabilidades en el Desarrollo

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 SSLGRANT ALL PRIVILEGES ON bbdd.* TO usuario@“host" IDENTIFIED BY ‘password' REQUIRE SSL

• Identificar unívocamente al usuarioGRANT ALL PRIVILEGES ON bbdd.* TO usuario@“host" IDENTIFIED BY ‘password' REQUIRE [X509|ISSUER|CIPHER]

2.3. Seguridad del SGBD (II)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 8: Riesgo y Vulnerabilidades en el Desarrollo

Persistencia de la Información

• Consolidación de las tablas a disco

• Automáticamente (incide en el rendimiento)# mysqld --flush

• Manualmente1) 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

2.3. Seguridad del SGBD (y III)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 9: Riesgo y Vulnerabilidades en el Desarrollo

Todo aquello que asumas que el usuario nunca hará, será lo primero que haga

cuando entre a tu Sitio Web

Cosas a tener en cuenta (I)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 10: Riesgo y Vulnerabilidades en el Desarrollo

Cuando la seguridad se ve comprometida, la responsabilidad suele recaer sobre el

programador de la aplicación

Tú tienes la culpa de todo!!Cosas a tener en cuenta (II)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 11: Riesgo y Vulnerabilidades en el Desarrollo

Nunca asumas que elAdministrador del Sistema

es un tipo competente

Cosas a tener en cuenta (III)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 12: Riesgo y Vulnerabilidades en el Desarrollo

Si además de programador eres elAdministrador del Sistema …

FELICIDADES!!YA ERES UN:

¡ ¡ BROWN EATER !!

Cosas a tener en cuenta (y IV)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 13: Riesgo y Vulnerabilidades en el Desarrollo

1. Definir condiciones de ejecución seguras para las bases de datos.

2. Definir la accesibilidad (ubicación y modo de acceso) 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ón de sesiones.

3. Seguridad en el Desarrollo Web

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 14: Riesgo y Vulnerabilidades en el Desarrollo

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 tablasOPTIMIZE 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.

3.1. Condiciones de las bases datos

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 15: Riesgo y Vulnerabilidades en el Desarrollo

1) Páginas Independientes (I)

3.2. Accesibilidad del Código (I)

index.html

pagina1.html pagina2.html pagina3.htmlpaginaN.html

Capa de SeguridadCapa de Acceso a BBDD

Capa de Código

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 16: Riesgo y Vulnerabilidades en el Desarrollo

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

3.2. Accesibilidad del Código (II)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 17: Riesgo y Vulnerabilidades en el Desarrollo

2) Dispatcher de Archivos (I)

3.2. Accesibilidad del Código (III)

1) index.php?file=pag1.php

include($file)

pagN.php

2) index.php?file=1

include(“ pag” .$file.” .php” )

Capa de SeguridadCapa de Acceso a BBDD

Capa de Código

3) Dispatcher de funciones

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 18: Riesgo y Vulnerabilidades en el Desarrollo

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

3.2. Accesibilidad del Código (IV)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 19: Riesgo y Vulnerabilidades en el Desarrollo

2) Dispatcher de Funciones (I)

3.2. Accesibilidad del Código (V)

1) index.php?opc=1

include(“ opciones.inc.php” );

switch ($opc) { case 1: func_opc1(params); default: func_index(params);}

opciones.inc.php

Capa de SeguridadCapa de Acceso a BBDD

Capa de Código

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 20: Riesgo y Vulnerabilidades en el Desarrollo

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

3.2. Accesibilidad del Código (VI)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 21: Riesgo y Vulnerabilidades en el Desarrollo

Protección de los archivos de inclusión

1) Cargarlos con: include_once(archivo);2) Siempre acabados en .php: seguridad.inc.php3) Si puede ser, alojarlos bajo el directorio raíz

4) Asegurar que solo se accede desde index.phpif (!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”);

3.2. Accesibilidad del Código (VII)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 22: Riesgo y Vulnerabilidades en el Desarrollo

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

3.2. Accesibilidad del Código (VIII)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 23: Riesgo y Vulnerabilidades en el Desarrollo

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>

3.2. Accesibilidad del Código (IX)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 24: Riesgo y Vulnerabilidades en el Desarrollo

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);

3.2. Accesibilidad del Código (y X)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 25: Riesgo y Vulnerabilidades en el Desarrollo

Diseño correcto de los formularios HTML

• 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:

- Comprobaciones de tipo y de rangos- Deshabilitar botones de envío al ser pulsados

3.3. Procesamiento de parámetros (I)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 26: Riesgo y Vulnerabilidades en el Desarrollo

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"];

3.3. Procesamiento de parámetros (II)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 27: Riesgo y Vulnerabilidades en el Desarrollo

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"];

3.3. Procesamiento de parámetros (III)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 28: Riesgo y Vulnerabilidades en el Desarrollo

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;

}

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 29: Riesgo y Vulnerabilidades en el Desarrollo

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;

}

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 30: Riesgo y Vulnerabilidades en el Desarrollo

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"];

3.3. Procesamiento de parámetros (IV)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 31: Riesgo y Vulnerabilidades en el Desarrollo

Eliminar código “maligno” (I)

5) Prevenir ataques XSS:

htmlentities()

Convierta caracteres a entidades HTMLhtmlspecialchars()

Convierte ciertos caracteres a HTML (“ , &, <, >)

strip_tags()

Elimina cadenas HTML y PHPpreg_replace()

on, <, >, %, ;, script, meta, applet, xml, link, style, frame, frameset, layer, base, bgsound…

3.3. Procesamiento de parámetros (V)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 32: Riesgo y Vulnerabilidades en el Desarrollo

Ejemplo XSS

<sc<script>ript>alert(“suerte”)</sc</script>ript>

function filtrar_XSS($string)

{

// Podemos aplicar filtros previos

// $string = htmlentities($string);

do {

$oldstring = string;

string = preg_replace(“PATRÓN”, “”, $string)

} while ($oldstring != $string);

return $string;

}

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 33: Riesgo y Vulnerabilidades en el Desarrollo

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 NUL2. Escapa los comandos y argumentos para usarlos

en la función exec() y similares

• Reforzar activando magic_quotes_gpc

3.3. Procesamiento de parámetros (y VI)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 34: Riesgo y Vulnerabilidades en el Desarrollo

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) ……

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 35: Riesgo y Vulnerabilidades en el Desarrollo

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">

3.4. Gestión de Sesiones (I)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 36: Riesgo y Vulnerabilidades en el Desarrollo

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();

3.4. Gestión de Sesiones (II)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 37: Riesgo y Vulnerabilidades en el Desarrollo

Ataques típicos usando el ID de sesión:

Cross-Site Request Forgeries

Session Fixation

Session Hijacking

3.4. Gestión de Sesiones (III)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 38: Riesgo y Vulnerabilidades en el Desarrollo

Fortificar el ID de sesión (I)

1) Cambiar valores por defecto de en php.ini:

[session]session.save_path = “ /tmp” ; Ej.: /var/www/sesssession.name = PHPSESSID ; Ej.: MY_SESSIDsession.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 0session.cache_expire = 180 ; ponerlo a 10 (min.)session.hash_function = 0 ; ponerlo a 1

3.4. Gestión de Sesiones (IV)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 39: Riesgo y Vulnerabilidades en el Desarrollo

Fortificar el ID de sesión (II)

2) Regenerar el ID se sesión periódicamente:

Previene los ataques de predicción y fuerza bruta. Reduce el tiempo de vida de ID´ s de sesión robados.

Hacerlo, al menos, al comenzar la sesión. A regenerar el ID, no se pierde la información de la sesión.

session_regenerate_id();

3.4. Gestión de Sesiones (V)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 40: Riesgo y Vulnerabilidades en el Desarrollo

Fortificar el ID de sesión (y III)

3) Utilizar técnicas de fingerprinting

Las sesiones que únicamente usan session_start() son vulnerables: predicción, fuerza bruta, secuestro, etc.

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.

3.4. Gestión de Sesiones (VI)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 41: Riesgo y Vulnerabilidades en el Desarrollo

session_start();

if (!isset($_SESSION[‘sesion_iniciada'])) {session_regenerate_id(); // Ejemplo de regeneración de ID$_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>

3.4. Gestión de Sesiones (VII)

fingerprinting

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 42: Riesgo y Vulnerabilidades en el Desarrollo

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ón en BBDD, 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}

3.4. Gestión de Sesiones (y VII)

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 43: Riesgo y Vulnerabilidades en el Desarrollo

Este documentohttp://www.esne.es/eventos.php?id=1

http://www.fistconferences.org/archivos.php

Documentación oficial de PHP sobre seguridadhttp://www.php.net/manual/es/security.php

Chris Shiflett PHP Security Guidehttp://www.shiflett.org/php-security.pdf

PHP Security Consortiumhttp://www.phpsec.org

XSS Preventionhttp://blog.bitflux.ch/wiki/XSS_Prevention

PHP Cryptographyhttp://www.phpmag.net/itr/online_artikel/psecom,id,667,nodeid,114.html

Authentication and Session Management on the Webhttp://www.westpoint.ltd.uk/advisories/Paul_Johnston_GSEC.pdf

FAQ sobre sesiones:http://www.webtaller.com/construccion/lenguajes/php/lessons/sesiones.php

4. Enlaces de interés

Javier Pascual Soriano, [email protected] – Escuela Superior de Negocios

Page 44: Riesgo y Vulnerabilidades en el Desarrollo

TO BE CONTINUED…

Page 45: Riesgo y Vulnerabilidades en el Desarrollo

Riesgos y Vulnerabilidades en el Desarrollo Web

Soluciones en PHP (y más)

FIST ConferenceBarcelona, 18 de marzo de 2005

Javier Pascual [email protected]

Departamento Tecnologías de la Información y las Comunicaciones