Nuevas tecnologías / viejas vulnerabilidades – Node.js (I)

Cada día vemos aparecer en el mercado nuevas tecnologías que permiten nuevas formas de desarrollo para la innovación. Sin ir más lejos, en el mundo de la web, la innovación conduce a la popularidad, haciendo que sitios como Google, Twitter y Facebook triunfen.

El principal problema de las nuevas tecnologías es que, aún teniendo la posibilidad de evitar problemas de seguridad conocidos, desafortunadamente, la mayoría de las veces esta no es el objetivo principal, por lo que estos errores se vuelven a repetir una y otra vez. Además de esto, las nuevas tecnologías también tienden a inventar nuevas clases de vulnerabilidad, o nuevas formas para explotar problemas de seguridad conocidos.

Un ejemplo práctico de que lo estoy diciendo es Node.js

¿Qué es Node.js?

El 8 de noviembre de 2009, Ryan Dahl presentó Node.js como un entorno de desarrollo en JavaScript de lado de servidor, totalmente asíncrono y orientado a eventos. Usa el motor de JavaScript V8 de Google, dotando a este entorno de una gran velocidad y agilidad, y sumando además una capacidad de Entrada/Salida realmente ligera y potente. Esto permite construir aplicaciones altamente escalables y escribir código que maneje miles de conexiones simultáneas en un solo equipo. Entre las compañías que usan esta tecnología destacamos LinkedIn, eBay, Yahoo!, Microsoft y nosotros mismos (S2 Grupo).

¿Qué es el V8?

V8 es el motor de JavaScript que Google usa en su navegador Chrome. Un motor normal de JavaScript, interpreta el código y lo ejecuta. El V8 es ultra-rápido, está escrito en C++ y se puede descargar por separado e incorporarlo a cualquier aplicación. Así nace Node.js, cambiando el propósito por el que se creó V8 y usándolo en el lado del servidor.

¿Para qué JavaScript en el lado del servidor?

La meta principal de Node.js es la de proporcionar una manera fácil de construir programas de red escalables. En lenguajes como Java™ y PHP, cada conexión genera un nuevo hilo con su respectiva reserva de memoria. Esto limita la cantidad de peticiones concurrentes que puede tener un sistema. Por ejemplo, un servidor muy común es Apache, el cual crea un nuevo hilo por cada conexión cliente-servidor. Esto funciona bien con pocas conexiones, pero a partir de 400 conexiones simultáneas, el número de segundos para atender las peticiones crece considerablemente. Así pues, Apache funciona bien en entornos clásicos, pero no es el mejor servidor para lograr máxima concurrencia.

Node.js resuelve este problema cambiando la forma en que se realiza una conexión con el servidor. En lugar de generar un nuevo hilo de SO para cada conexión, cada conexión entra en el bucle de ejecución y dispara el evento dentro del “pool” de trabajadores. De esta forma, nunca se quedará en punto muerto, dado que no se permiten bloqueos y no se bloquea directamente las llamadas de E/S, permitiendo así miles de sesiones concurrentes (en un sistema UNIX este límite puede rondar por las 65.000 conexiones).

¿Cuándo usar Node.js?

Node.js está extremadamente bien diseñado para situaciones en la que se espere una gran cantidad de tráfico y donde la lógica del servidor y el procesamiento requeridos sean sencillas para dar una respuesta lo antes posible. Node.js es especialmente bueno en aplicaciones web que necesiten conexiones persistentes con el navegador del cliente. Usando ciertas librerías, en concreto socket.io, puedes hacer que una aplicación envíe datos al usuario en tiempo real; es decir, que el navegador mantenga la conexión siempre abierta y reciba continuamente nuevos datos cuando se requiera. Hay que entender que, aunque se puede usar como servidor de páginas web “clásicas”, no se diseñó para ese fin. Algunos ejemplos de uso:

  • Servicios Web que proporcionen APIs RESTful.
  • “Timelines” de Twitter.
  • Aplicaciones de única página.
  • Videojuegos de varios jugadores.
  • Aplicaciones tiempo real (Chats, cuadros de mando).

Node.js dispone de un gestor de módulos (librerías, plugins, frameworks) npm (Node Package Manager), que amplían la funcionalidad de este y facilitan tareas. En otro futuro post trataremos de hablar de varios frameworks típicos de Node.js, en concreto de Fusker, que es un firewall de aplicación que previene y maneja una gran cantidad de ataques en Node.js.

Entre estas librerías, destacaremos la ya nombrada Socket.io, que es una librería que nos permite manejar eventos en tiempo real mediante una conexión TCP. Socket.io la cual tiene como objetivo hacer que las aplicaciones en tiempo real sean posibles en todos los navegadores y dispositivos móviles, borrando las diferencias entre los mecanismos de transporte (WebSocket, Adobe® Flash® Socket, AJAX long polling, AJAX multipart streaming, Forever Iframe, JSONP Polling).

Estas comunicaciones se pueden poner detrás de un servidor clásico como podría ser Apache o Nginx tal y como explica Vicente Domínguez en su post.

Un poco de código

Para comenzar, podemos descargar Node.js de la página de la aplicación http://nodejs.org/, para varios sistemas. En mi caso he realizado las pruebas con la última versión (tar.gz) para Linux.

Una vez descargado y funcionando vamos a comenzar escribiendo la aplicación en un fichero js. Editamos un archivo “ejemplo-1.js” y escribimos el siguiente código:

var http = require('http');
http.createServer(function (req, res) {
     res.writeHead(200, {'Content-Type': 'text/plain'});
     res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

Ahora desde la consola lanzamos la aplicación:

$ node ejemplo-1.js

Para los que no estéis familiarizados con JavaScript, existen multitud de tutoriales en internet, no es el propósito de este post explicar línea por línea que hacen los programas. En resumen, vemos que “ejemplo-1.js” crea un servidor que escucha en el puerto 1337 y, ante cualquier petición a http://127.0.0.1 devuelve un texto plano “Hello World”.

En el siguiente post, apoyándome en la presentación que hizo Sven Vetsch (Redguard AG – www.redguard.ch) para el Application Security Forum de 2012, trataré de mostrar cómo pueden afectar las clásicas vulnerabilidades (XSS reflejado, inyección de JS en el servidor, ejecución de código remoto).

Listas de control de acceso (ACL)

Es posible que esto que os voy a contar a muchos de vosotros no os venga de nuevo, pero me ha parecido interesante exponer la experiencia que me ha hecho redescubrir algo tan básico como son las Listas de Control de Acceso (ACL). Yo conocía el concepto de ACL en dispositivos de red (como routers), pero no recordaba que estas podían usarse en el desarrollo de un software para proteger recursos según roles. Al final no deja de ser un simple método de usuarios y roles, pero como en la navaja de Occam, la solución más simple siempre suele ser la correcta.

Estando el otro día reunidos varios compañeros para la definición de requerimientos de un software que vamos a desarrollar, se nos planteó la duda de cómo íbamos a gestionar los permisos en dicha aplicación. La aplicación se va a desarrollar con el framework de php CakePHP, y un compañero se dio cuenta que este entorno tiene implementadas las ACL. Buscando por Internet su funcionamiento, encontré el ejemplo que los chicos de Cake han hecho, y me parece que mejor no se puede explicar. Voy a tratar de hacer un resumen un poco más gráfico que ellos, pero si no queda claro, en su web está toda la explicación.

Lo primero que hay que entender son dos conceptos muy importantes; quién o qué quiere poder acceder a que cosa. Al quién o qué (generalmente usuarios) lo llamaremos ARO (ARO – Access Request Object – Objeto que solicita el control de algo) y la cosa la llamaremos ACO (ACO – Access Control Object – Objeto que se quiere controlar). Vamos a utilizar los mismos ARO y ACO que se utilizan en el ejemplo de Cake y que hacen referencia a los personajes del Señor de los Anillos. En la siguiente tabla vemos una lista de los distintos ARO que conforman nuestro ejemplo:

ARO

A los distintos actores de nuestro ejemplo se les tiene que otorgar el acceso a distintos objetos, según quienes sean o que rol desempeñan en la historia (o aplicación). Estos son los distintos objetos:

ACO

Este ejemplo de matriz de permisos funciona bien en este caso, pues se conocen los actores y objetos que intervienen, pero queda claro que no es muy escalable ya que para casa objeto nuevo que pueda entrar en escena, o cada personaje, se han de “revisar” uno a uno quién tiene permisos sobre qué. Ahora imaginemos que hemos de modelizar esto para todos y cada uno de los personajes de toda la saga. Está claro que se hace un poco difícil y tedioso. Si además esto se ha de programar, ni os cuento. En otras palabras, estaría muy bien que, una vez terminada la batalla, los hobbits pudieran acceder a la cerveza y al jamón; en otras palabras, otorgar individualmente permisos a hobbits es tedioso y propenso a errores, mientras que aplicarles un cambio en cascada es mucho más fácil.

La ACL se suele implementar en una estructura de árbol y generalmente, existe uno para los AROs y uno para los ACOs. Organizando los objetos así, los permisos se gestionan de forma granular y se mantiene una visión general. La siguiente figura muestra un ejemplo de los ARO agrupados por tipo (o rol).

De esta forma ahora podemos ir dando/quitando los permisos a los distintos objetos según por que rama del árbol vayamos descendiendo. Una primera aproximación sería, negar todo a la comunidad, y a partir de ahí ir otorgando los permisos correspondientes según se muestra en la siguiente figura, en la que quedan superpuestos los dos árboles.

Si vemos el esquema, notaremos que a los guerreros (Legolas, Aragorn, Gandalf) se les permite el jamón, la cerveza y las armas. Además, a los magos se les permite da diplomacia. En el caso de los hobbits, vemos que por defecto todos ellos tienen permiso de cerveza, así que cualquier hobbit nuevo que añadamos (por ejemplo Sam), podrá acceder a ella. Sin embargo a título personal, se le ha denegado la cerveza a Merry (al parecer abusaba de ella), y por último se le permite a Frodo llevar el Anillo.

Vamos, que espero que haya quedado claro la potencia de otorgar/denegar permisos a los ARO de los distintos ACO que forman nuestra aplicación. Está claro que esto nada tiene que ver con el “Login” en ella (que sería como pertenecer o no a la comunidad del anillo), si no que lo que se establece son los permisos sobre partes concretas de la aplicación.

Una vez visto esto, queda pendiente en otro post, explicar como se usa esto en CakePHP, con permiso de Nedim ;)

Bastionado de un servidor WEB Apache (II)

Como ya vimos en el anterior post, lo primero que deberíamos hacer al instalar un apache es ocultar cierta información que podría ser usada para ponérselo más fácil a algún malintencionado para que nos ataque. Como bien se dijo en los comentarios, esto no proporciona seguridad en si mismo, si no que dificulta (un poco) un posible ataque.

Otro factor que creemos que debería tenerse en cuenta, sin entrar todavía en la protección activa, es el de ajustar la configuración según el uso se va a dar a la aplicación web que apache va a servir. Pasemos a describir los métodos mas esenciales que debemos tener en cuenta.

Segundo paso: Activa lo justo y necesario

Lo primero que se podría realizar, para asegurar que cada directorio tenga activado únicamente lo que se necesite, es desactivar las Options y “overrides” para el servidor, teniendo que ir activando una a una, de manera explícita, las que necesitemos. Supongamos que tenemos una aplicación en www, entonces podríamos hacer algo así:

<Directory />
Order Deny,Allow
Deny from all
Options None
AllowOverride None
</Directory>

<Directory /www>
Order Allow,Deny
Allow from all
</Directory>

Por otro lado, una de las recomendaciones más comunes a la hora de configurar apache es la de evitar que éste tenga la posibilidad de seguir enlaces simbólicos. Esto se hace para evitar que un enlace simbólico malicioso pueda acceder a archivos fuera de la estructura de directorios, con el consecuente riesgo de que estos sean manipulados o destruidos. Para evitar esto, debemos marcar la directiva FollowSymLinks con un “-” en el directorio especificado.

<Directory>
...
Options –FollowSymLinks
...
</Directory>

En el caso que se necesite que se puedan seguir enlaces simbólicos, puede usarse SymLinksIfOwnerMatch, que sirve para que el servidor siga los enlaces simbólicos siempre y cuando los ficheros o directorios finales pertenezcan al mismo usuario que el propio enlace.

Es importante desactivar la opción de ejecución de CGI en todos los directorios de la web, salvo en uno concreto destinado a alojar todos los ejecutables. De esta forma se minimiza la posibilidad de que un atacante ejecute código de forma aleatoria. Lo desactivamos de la misma forma que los enlaces simbólicos.

<Directory>
...
Options -ExecCGI
...
</Directory>

En muchos casos la configuración para un directorio en concreto está en el archivo .htaccess. Las siguientes directivas evitan, mediante el uso de una expresión regular, que se puedan descargar los archivos que empiezan por “.ht”:

AccessFileName .httpdoverride
<Files ~ “^\.ht”>
Order allow,deny
Deny from all
Satisfy All
</Files>

Por supuesto, no actives módulos innecesarios, y desactiva aquellos que no vayas a usar.

Otro factor que podemos tener en cuenta es controlar desde dónde se va a consultar la aplicación web. Si el objetivo es que sólo se consulte desde una intranet conocida, o desde una única IP, esto se puede configurar de la siguiente forma:

<Directory>
...
Order Deny,Allow
Deny from all
Allow from 192.168.0.0/16
...
</Directory>

para una red, o:

<Directory>
...
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
...
</Directory>

para una única IP.

En las siguientes entregas hablaremos un poco más de que parámetros se pueden usar para ayudar un poco más en la defensa e instalaremos algunos módulos exclusivos para defendernos de varios tipos de ataque.

Método de login “seguro” sin SSL

El objetivo de esta entrada es mostrar una manera de hacer un poco más seguro el acceso a una aplicación web (login) si ésta no dispone de SSL (HTTPS). Para los que son duchos en la seguridad, puede que esto les pueda parecer simple, e incluso obvio, pero en muchas empresas de desarrollo de páginas web, ni se plantean lo peligroso que puede llegar a ser el envío de credenciales en claro a través de Internet.

Un problema que nos encontramos los que nos dedicamos al desarrollo de software, y en concreto de páginas web, suele ser que el cliente no quiere (o no puede) pagar un certificado de servidor para su portal. Lo que tampoco queremos es que nuestras contraseñas vayan por la red en claro, siendo vulnerables a cualquiera que ande “esnifando” por la red. Supongo que existen varias soluciones a este problema, yo os voy a contar una que no es solución y otra que es un poco mejor (en temas de seguridad nunca me atrevería a decir que es infalible, porque creo que nada lo es). Para los ejemplos voy a usar como usuario a bob y como contraseña bob123.

Lo que NO es una solución

Si estáis tratando de solventar este problema, probablemente os encontraréis con sitios que os dicen que la solución pasa por cifrar la contraseña con Javascript (aprovecho para recordar que el verbo encriptar no existe, y cada vez que alguien la usa se muere un gatito) justo antes de que el formulario se mande.

Normalmente suelen decir que hagas un hash de la contraseña y así esta no viajará en claro por la red. Esto no es una solución porque si yo soy un “hacker” maligno y consigo ver la comunicación, no podré leer la contraseña bob123, pero si que veré 2acba7f51acfd4fd5102ad090fc612ee, que es el resultado de aplicar una función hash (md5) a bob123.

La cosa es que a mí, como atacante, me da lo mismo ver lo primero que lo segundo, ya que sé que si mando la petición de login a la página “web” poniendo como usuario bob y como contraseña 2acba7f51acfd4fd5102ad090fc612ee voy a poder acceder a la aplicación (entiéndase que esto se realizará usando alguna herramienta de manipulación de peticiones HTTP como burp o tamperdata etc…). Además, es muy común que las contraseñas en las bases de datos se guarden cifradas con este mismo método (y el que las guarde en claro, tiene un problema muy grave), con lo que, en realidad, puede que lo que esté viajando por la red sea la contraseña en si misma.

Una posible solución

La solución que creo más segura es la de “simular” la conexión SSL mediante un par de claves pública/privada por petición. De esta manera el servidor mandará la clave pública, que le servirá al navegador para cifrar la información, y guarda la clave privada, que sólo sirve para descifrar esa información. Para realizar esto haremos uso del Javascript de forma similar a la anterior. La diferencia es que esta vez cuando el cliente (navegador web) haga la petición a la pantalla de login, el servidor generará un par de claves nuevas.

Creo que es de buena praxis cifrar, además de la contraseña, el nombre de usuario ya que cuantas menos pistas demos a los atacantes mejor. Así pues, cada vez que le mandemos la información de acceso al servidor, ésta será diferente, y aunque vieran que el usuario es 0a42b6b9dcd569f990d y la contraseña es cde40f4ff73c5a24eb904, esto sólo será válido una vez ya que a cada petición el servidor nos manda una clave pública distinta. Hay que tener mucho cuidado con esto, dado que si el servidor usa como semilla de generación de claves algo obvio, como el tiempo, se podría mediante repetidas peticiones de la página de login, obtener el algoritmo que esta usando para generarlas y podría llegar a obtener la clave privada para una petición y descifrar así la información.

Bastionado de un servidor WEB Apache (I)

Este es el primer post de una serie elaborada por José Luis Chica y Guillermo Mir. En ésta se quieren recoger los pasos que se pueden realizar (en muchos casos creemos debería ser imperativo realizar) para instalar y securizar un servidor Apache. Existen múltiples entradas y páginas que explican, de manera separada, como realizar diversas tareas, pero nosotros nos hemos propuesto exponerlas todas en esta serie, de manera que puedan servir de guía a todos aquellas personas que se han de instalar o gestionar un servidor de estas características. El sistema operativo que vamos a usar en los ejemplos es un Linux con distribución Debian Squeeze (6), pero esto sólo va a influir en las rutas dónde se encuentran los distintos ficheros de configuración.

Primer paso: Ocultando información

Una instalación por defecto de Apache muestra cierta información relacionada con el entorno donde ha sido desplegado. Dependiendo del sistema operativo, esta información puede variar pero en general, un posible atacante puede recopilar datos muy útiles que le puedan aportar vectores de ataque adicionales. Así pues, solo tendría que comprobar si existen vulnerabilidades conocidas en las versiones de las tecnologías utilizadas.

[Read more…]

PHPIDS securiza tu web

En uno de los últimos portales web que he tenido que desarrollar una de las principales premisas era que tenía que ser muy seguro. El nuevo portal tenía que suplir a una versión hecha en html puro, sin código en el servidor. ¿Para qué cambiar si la versión anterior ya era segura? Tampoco entraré en más detalles pero, ¿os acordáis de esas “bonitas” webs con montones de gifs animados y colores espartanos? Esas páginas eran bonitas al lado de esta. Al grano. Para el desarrollo del nuevo portal se estuvieron haciendo pruebas con varios CMS (Gestores de contenidos) en PHP. ¿Por qué en PHP? Pues porque los recursos del servidor eran limitados, y porque me gusta. Al final nos decantamos por Drupal, ya que ofrecía a priori una robustez y seguridad que otros no. ¡Ah!, y porque me gusta.

Una vez tenía el portal ya bastante terminado, me puse a indagar como podía añadirle más seguridad. Al final, en todos los gestores terminas instalando una infinidad de “plugins” (módulos) hechos por terceros que, aunque sea una comunidad muy rápida en resolver los problemas de seguridad, siempre existe cierto riesgo. Fue entonces cuando di con un módulo de Drupal llamado PHPIDS. El módulo actúa de “envoltorio” del programa PHPIDS.

Encontré también un enlace a howforge dónde se documenta la instalación de éste. Voy a resumir dicha instalación, ya que las bondades de este programa están bien resumidas en este post de Security By Default, y luego voy os explicaré como lo hice en Drupal.

Instalación Básica de PHPIDS

Esta instalación sirve para cualquier aplicación PHP, incluyendo todos sus CMS (Drupal, Joomla, WordPress, Moodle etc…). El ejemplo está realizado en una máquina Debian Squeeze.

1) Descargamos el programa de la web. En estos momentos en su versión 0.7. y descomprimimos el paquete.

$ wget http://phpids.org/files/phpids-0.7.tar.gz
$ tar zxvf phpids-0.7.tar.gz

2) Creamos un directorio en la ruta dónde vayamos a ubicar la web y copiamos la el subdirectorio ‘lib’.

$ mkdir /var/www/phpids
$ mv lib/ /var/www/phpids/

3) En el directorio de la aplicación IDS, creamos ‘tmp’ y le damos permisos de escritura (en este caso hacemos propietario del directorio) al usuario del servidor web (en apache a www-data).

$ mkdir  /var/www/phpids/lib/IDS/tmp
$ chown -R www-data:www-data /var/www/phpids/lib/IDS/tmp

4) Copiamos el archivo IDS/Config/Config.ini.php en Config.ini y modificamos las rutas por defecto.

; PHPIDS Config.ini
...
[General]
 filter_type     = xml
 filter_path     = /var/www/phpids/lib/IDS/default_filter.xml
 tmp_path        = /var/www/phpids/lib/IDS/tmp
 scan_keys       = false
...
[Logging]
 ; file logging
 path            = /var/www/phpids/lib/IDS/tmp/phpids_log.txt
...
[Caching]

 ; caching:      session|file|database|memcached|none
 caching         = file
 expiration_time = 600

 ; file cache
 path            = /var/www/phpids/lib/IDS/tmp/default_filter.cache
...
 ; memcached
 ;host           = localhost
 ;port           = 11211
 ;key_prefix     = PHPIDS
 ;tmp_path       = /var/www/phpids/lib/IDS/tmp/memcache.timestamp

Como prueba de concepto, creamos un pequeño script php que nos muestra un mensaje de OK, si la petición es correcta, o nos muestra una traza del error en caso de un intento de ataque.

<?php
set_include_path(
get_include_path().PATH_SEPARATOR.'/var/www/phpids/lib');
require_once 'IDS/Init.php';
$request = array(
      'REQUEST' => $_REQUEST,
      'GET' => $_GET,
      'POST' => $_POST,
      'COOKIE' => $_COOKIE );
$init = IDS_Init::init('/var/www/phpids/lib/IDS/Config/Config.ini');
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();
if (!$result->isEmpty()) {
   echo $result;
   require_once 'IDS/Log/File.php';
   require_once 'IDS/Log/Composite.php';
   $cLog = new IDS_Log_Composite();
   $cLog->addLogger(IDS_Log_File::getInstance($init));
   $cLog->execute($result);
  }else print(“<h1>Todo OK!</h1>”);
?>

En la web de howforge encontraréis este ejemplo y otros un poco más desarrollados, así como la explicación para poder usar PHPIDA en todas las páginas PHP sin tener que modificar una a una usando la propiedad de PHP auto_prepend_file.

Si no tienes ni idea de este gestor y no quieres tenerla, puedes dejar de leer, ya que a partir de aquí puede que no te interese mucho.

PHPIDS en Drupal

Otra manera de usar PHPIDS es mediante el módulo de Drupal (ver la página de PHPIDS en la web de Drupal). Este módulo permite configurar el programa desde la consola de Drupal y registra los eventos en la base de datos de este, para poder acceder a ellos de una forma más visual. La instalación es bastante sencilla.

1) Descargar el último paquete de PHPIDS si no lo teniamos.
2) Se descomprime el tar en el directorio para las bibliotecas externas de Drupal (/sites/all/libraries/phpids-0.7).
3) Se crea un directorio de archivos temporales de escritura para PHPIDS para almacenar en caché los filtros y se le añade permisos como en el apartado anterior (phpids-0.7/lib/IDS/tmp)
4) Se copia, instala el módulo de Drupal PHPIDS.

En la configuración (http://miweb/es/admin/settings/logging) se establece:

General
PHP-IDS Path: /opt/drupal/sites/all/libraries/phpids-0.7/lib
PHP-IDS Temp Path: /opt/drupal/sites/all/libraries/phpids-0.7/lib/IDS/tmp
Mail impact: 9

Filter settings.
Anonymous users: "Log Anonymous users without actions" 
Authenticated users: "Log Authenticated users users without actions"

El resto se quedan en blanco por el momento.

Con esto ya se tiene instalado y registrando los “accesos indebidos”. No se han tomado medidas, lo único que hacemos es registrar, de manera que si vamos a http://miweb/es/admin/reports/dblog podemos filtrar los eventos de PHPIDS como muestra la figura:

Y si hacemos clic sobre el enlace del mensaje, se puede ver todo el detalle:


En ambos casos se PHPIDS se puede configurar de varias maneras: que registre, que bloquee, distintos grados de seguridad etc. Espero que este post al menos haya servido para mostrar que no es difícil poner un +1 a la seguridad de una web PHP.

Filtros de acción en MVC 3 .NET (y II)

Siguiendo con los filtros de acción en .NET, y partiendo de la base de lo que se hizo en el post anterior, esta vez voy a mostrar cómo crear un filtro de acción propio. No es el motivo de este post explicar cómo gestiona Visual Studio las clases y la base de datos de autenticación, así que se usará el sistema que viene por defecto para la demostración.

Si recordáis el estado del programa al finalizar el pasado post, añadimos el filtro [Authorize] en el controlador de la página principal, en la función de About, de manera que al tratar de ver esta página, la aplicación nos redirigía a la página de LogOn. El siguiente paso sería crear dos usuarios distintos en la aplicación. Al primero le voy a llamar ‘pedro’ y al segundo ‘juan’. El filtro va a permitir únicamente a ‘juan’ ver la sección “About”. Así pues, manos a la obra.

Al ejecutar la aplicación (F5) e intentar acceder a la sección ‘About’ esta nos redirige la página de ‘LogOn’, en la que se encuentra un enlace a ‘Register‘.


Pantalla de LogOn

Para registrar un nuevo usuario sólo se necesita un nombre de usuario, un correo y una contraseña.


Pantalla de registro

Una vez hecho esto se puede observar que, al estar autenticados en el sistema, ya se permite ver la página ‘About’. Esto es porque el filtro que estamos usando [Authorize] sólo comprueba que el usuario esté registrado en el sistema.

Pasos para realizar el filtro:

1) Se crea una nueva carpeta “Infrastructure” dónde se creará la clase. Para ello, en el ‘Explorador de soluciones’, que se encuentra en la parte derecha de la pantalla, haciendo clic con el botón derecho del ratón aparece un menú emergente. Agregar -> Nueva carpeta: Infrastructure

2) Sobre la nueva carpeta, se procede de la misma forma, Agregar -> Clase: CustomFilterAttribute.cs


Pantalla de creación de clase

3) El código de la clase “CustomFilterAttribute” será:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
    
public class CustomAuthorizeAttribute : AuthorizeAttribute
{  
    public override void OnAuthorization(AuthorizationContext filterContext){        
        if (filterContext == null){
            throw new ArgumentNullException("AuthorizeFilterAttribute");
        }        
        String username = filterContext.HttpContext.User.Identity.Name;  // 1
        List userlist = Users.Split(',').ToList();                       // 2
        if (!userlist.Contains(username)){                               // 3
            filterContext.Result = new HttpUnauthorizedResult();
        }        
    }
}

Clase CustomFilterAttribute

4) La clase hereda de ‘AuthorizeAttribute’ e implementamos el método ‘OnAuthorization’, que se llama en el momento de la autorización. Una vez comprobado que el contexto no es nulo, creamos la funcionalidad:

// 1 Se obtiene el identificador (username) del usuario en el sistema (si es que este existe).

// 2 Se obtiene una lista de los usuarios que tienen permiso según el filtro (luego se verá como se asignan).

// 3 Si el usuario no está en la lista de permitidos, se asigna un ‘HttUnauthorizeResult’ al contexto, para que se hagan las acciones pertinentes (en este caso, volver al ‘LogOn’).

5) Por último sólo queda modificar el controlador para decir que únicamente pedro tenga acceso a la página de ‘About’.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcSample.Controllers
{
    public class HomeController : Controller
    {        
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";
            return View();
        }
        [CustomAuthorizeAttribute(Users="pedro")] //Llamada a CustomAuthorize
        public ActionResult About(){
            return View();
        }
    }
}

Llamada a CustomAttributte

6) Se puede ver que la acción “About” sólo está permitida para el usuario “pedro”.

Si ahora se ejecuta la aplicación (si se estaba ejecutando, recompilar con ctrl+shift+b), se pueden hacer pruebas con los dos usuarios creados, y ver que sólo “pedro” podrá acceder a la sección “About”.

Aunque este ejemplo es un poco “tonto”, creo que sirve bien para ilustrar cómo crear un filtro de acción propio y en este poder añadir la lógica que se requiera para la aplicación.

(N.d.E. Nada más hasta el lunes. Pasen un buen fin de semana y una feliz nochebuena y día de Navidad. Nos vemos, si quieren, aquí mismo el lunes que viene)

Filtros de acción en MVC 3 .NET (I)

Hace ya algún tiempo, antes que la vida me llevara por estos lares en los que resido, solía realizar mis “creaciones” con un programita que algunos conoceréis y otros no, llamado Microsoft Visual Studio. Sí, habéis leído bien, Microsoft. Adorado y odiado a partes iguales, hay que reconocerle que esta gente es muy buena en muchas cosas (opinión personal, y con esto no quiero decir que el resto no lo sea), y hace fácil el desarrollo de aplicaciones para su plataforma. No es el motivo del post hacer publicidad de este producto, lo que quiero mostraros es lo fácil que pueden resultar algunas tareas gracias a este entorno (del que existe versión gratuita y con la que he realizado este ejemplo).

Lo primero, he descargado una aplicación llamada “Microsoft Web Platform Installer”, que es un gestor de descargas de software. Si realmente queréis probar lo que voy a tratar de exponer, sólo tenéis que ir a http://www.asp.net/get-started y seguir las instrucciones para instalar el “Microsoft Visual Web Developer Express” y el Framework “ASP.NET MVC 3” con el que realizaré este ejemplo. Como veis, voy a usar el patrón de diseño MVC con el Framework que Microsoft proporciona.

Como ya sabréis, en el patrón MVC (Modelo Vista Controlador), el controlador es el que se encarga de recibir las peticiones de una vista en concreto, y llamar al método o acción correspondiente a ese evento. Por ejemplo, si un usuario hace “clic” en un enlace, el controlador definirá la acción que se ha de realizar, como podría ser ir a una sección de la web en concreto. Imaginemos ahora que nos gustaría realizar cierta tarea (crear algún tipo de lógica) antes de que se ejecute el proceso asignado a una acción. En el caso anterior, querríamos saber si el usuario que solicita ver la página del enlace tiene permisos para ello. Ahí es dónde entran los filtros de acción.

¿Qué es un filtro de acción?

Un filtro de acción es un atributo que, cuando se adjunta a una clase Controlador (Controller) o a un método de este, añade cierta lógica a la acción solicitada. La gracia del asunto radica en que se puede extraer cualquier tipo de lógica que no tenga porque pertenecer al controlador en si mismo. Esto nos permite reutilizar este filtro en los controladores que queramos.

ASP.NET MVC incluye unos cuantos filtros de acción predefinidos, de los que podemos extender, o bien crear nuestros propios filtros, implementando las interfaces que nos proporcionan. En esta página http://msdn.microsoft.com/en-us/library/dd410209.aspx de la que he sacado gran parte de la información que os cuento, podéis encontrar una descripción de estos.

Vaaaale… ya veo que algunos os estáis asustando porque no sabéis de que hablo y probablemente si no sois desarrolladores esto os puede sonar a chino, pero con el ejemplo lo entenderéis, o eso espero. En este post vamos a ver como se usa el filtro de autorización que viene por defecto, y dejamos para un segundo post la implementación (extensión) de este.

Usar el filtro de acción

Asumiendo que hemos instalado la plataforma de desarrollo, vamos a crear un nuevo proyecto [Archivo -> Nuevo Proyecto] y elegiremos “Aplicación Web de ASP.NET MVC 3”, dentro de las plantillas Visual C# | Web. Llamaremos a la aplicación MvcSample y le damos a “Aceptar”.

Esto nos generará una aplicación web básica con una pantalla “Inicio” (Home) y una pantalla de “Acerca de” (About). Si probáis la aplicación (F5 o dándole al botón de play de color verde), se os abrirá en navegador predefinido en la pantalla principal, que contiene un menú en la derecha para navegar entre el “Inicio” y el “Acerca de”.

Podéis probar a navegar entre ambas opciones (olvidemos el enlace a [Iniciar sesión] por el momento). Veréis que podéis hacerlo sin problemas. Bien, pues vamos a asignar un filtro predefinido de autorización a la pantalla de “Acerca de” de manera que, si no estamos logados en la aplicación, esta nos va a redirigir a la pantalla de “[Inicio de sesión]” (LogOn).

En la parte izquierda de la pantalla encontramos el “Explorador de soluciones”. Ahí están todas las carpetas que tiene nuestro proyecto y que no voy a comentar ahora.

Vamos a la carpeta de “Controllers”, abrimos el archivo “HomeController.cs” que es el controlador de la pantalla de principal, y vemos que existen dos métodos. El primero llamado “Index()” lo único que hace es devolver la “Vista” principal a la que le pasa en nombre de la aplicación “ASP.NET MVC”. Esta acción es la que se ejecuta al hacer clic en “Inicio”. En segundo lugar tenemos el método About(), que es el que se llama cuando se hace clic en el enlace “Acerca de”.

Bien, lo último que nos queda por hacer es asignar el filtro de autorización (Authorize) predefinido antes de llamada del método About() y con esto ya estaremos bloqueando el acceso a esta llamada a todo usuario no validado en la página.

Si ahora volvéis a compilar la aplicación (ctrl.+alt. + b) observaréis que ya no tenéis acceso a la página de “Acerca de” y se os redirige de forma automática a la pantalla de LogOn.

Sin entrar en más detalles, notar lo sencillo y limpio que es proteger partes, o toda nuestra aplicación a personas no autorizadas. En este caso sólo he usado el filtro por defecto, en el siguiente post comentaré como podemos implementar nuestro propio filtro de autorización.

Vectores de ataque del HTML 5

Brevísimo resumen del HTML

Corria el año 1995 cuando un organismo llamado IETF (Internet Engineering Task Force), logró organizar a un grupo de trabajo con el fin de publicar un estándar para un lenguaje de marcado, inventado por Tim Berners-Lee años antes. Fue el 22 de septiembre de ese año cuando vio la luz el primer estándar del, hoy ya famoso, HTML. Curiosamente, a esta primera revisión oficial del lenguaje, se la denominó HTML 2.0.

Un año más tarde, HTML “cambió de manos” y paso a ser la W3C (World Wide Web Consortium), la encargada de los nuevos estándares.

El 24 de Abril de 1998 se publicó una versión corregida, de una publicación original del 18 de Diciembre de 1997, llamada HTML 4.0. Esta supuso un gran salto desde las versiones anteriores. Entre sus novedades más destacadas se encontraban las hojas de estilos CSS, la posibilidad de incluir pequeños programas o scripts en las páginas web, mejora de la accesibilidad, tablas complejas y mejoras en los formularios.

A partir de ahí, y hasta la salida del HTML5, se han ido realizando modificaciones y revisiones del estándar, convirtiendo la web en lo que conocemos hoy en día, como dice Oscar Campos (genbetadev.com): “Hoy en día, la web es un sitio maravilloso donde procrastinar como campeones y navegar como jamás Chanquete lo hubiera siquiera imaginado.

[Read more…]

Las pifias de “Hollywood”

Hace ya varios años, cuando aún estaba estudiando en la facultad, me surgió la oportunidad de ejercer de moderador en una “asignatura” sobre las Ingenierías (y más concretamente, la informática) en el cine. Cada sesión se componía de dos partes: el visionado de una película y un debate posterior. Lo primero que tuve que hacer fue “documentarme” un poquillo, para decidir que películas podían ser interesantes, y que se podía sacar de ellas.

Esta claro que hoy en día no hace falta ver una película que hable de informática para ver el uso de ordenadores en ella, y se podría perdonar la falta de rigurosidad que estas pudieran tener. Lo triste es ver que en las películas en las que la informática forma parte de la trama principal, es las en las que más barbaridades se llegan a ver.

Realizando dicha labor, me encontré con varios blogs que hablaban de las grandes “pifias” que había cometido la industria cinematográfica con la informática. No recuerdo muy bien todos ellos, pero la mayoría estaba de acuerdo con qué películas habían cometido los mayores errores. Todos los blogs coinciden en que las películas que hablan de los hackers son aquellas que peor reflejan la realidad. Por ejemplo los “hackers” saben usar cualquier sistema operativo que además debe estar en suspensión o algo así, porque normalmente tienen una velocidad de arranque que ya quisiéramos, y son capaces de desproteger cualquier sistema en menos de 5 minutos. Un claro ejemplo de esta situación, llevada al límite de lo absurdo es cuando, en Operación Swordfish (Swordfish, 2001), Stanley (Hugh ‘Lobezno’ Jackman) tiene que demostrar que puede entrar en el ordenador del departamento de defensa americano en apenas un minuto, mientras una chica guapa se propone distraerle de una manera un tanto… original, y John “Vincent Vega” Travolta le apunta con una pistola en la sien. Como una imagen vale más que mil palabras os dejo un enlace al vídeo, juzgar vosotros mismos.

Otra capacidad que tienen los hackers es la de programar a toda velocidad. Lo más común son los virus (debe ser que son fáciles de hacer, hecho uno…). Véase por ejemplo Independence Day (Independence Day, 1996), en la que programan un virus capaz de desarmar los escudos de las naves alienígenas (¿os habéis planteado si usarán los Alien TCP/IP para sus comunicaciones?). No olvidéis tampoco que, si accedéis a www.fbi.org u otro organismo semejante, vais a la sección “secret files” y, con varios intentos accederéis a los datos más secretos del mundo. Aparte de las películas ya mencionadas, otras en las que aparecen “superhackers” son: The Italian Job (The Italian Job, 2003), Hackers (Hackers, 1995), Misión Imposible (Impossible Mission, 1996), Parque Jurásico (Jurassic Park, 1993)…

Una cosa sí hay que envidiar a los productores americanos: su capacidad de diseñar interfaces 3D “super chulas”, con una velocidad que ni Google. Los archivos que necesitas suelen estar escondidos detrás del cubo verde (otra vez Jurassic Park es un buen ejemplo de ello… ¡ah, y es Unix!), y no se puede acceder a ellos con un par de clicks, lo que hay que hacer es “aporrear” el teclado a toda velocidad para parecer que eres un gran informático. Son unos sistemas basados en la estadística: contra cuanto más rápido teclees, más posibilidades tienes de acertar la combinación de teclas necesarias para llegar al archivo. Eso sí, aunque son sistemas con una capacidad de búsqueda tremenda, tienen un punto flaco, y es a la hora de copiar archivos cruciales para resolver una trama de conspiración a nivel mundial, a un USB, un CD o mandarlos por correo. En ese momento la barra de progreso del copiado se vuelve “leeeeeeeeentaaaaaaaaaaaaaaa” dando tiempo así a que el malote aparezca por la puerta, para dar más tensión a la trama. Por nombrar alguna película más, que no deberíais ver ni aunque la vida os fuera en ello, Firewall (Firewall, 2006) dónde tito Harrison “Jones” Ford es un agente de seguridad, capaz de montar un escáner de última generación con la barra lectora de un fax/multifunción y con un iPod mini mediante la entrada de los cascos (llora McGyver), y sin saber como la cosa funciona de lujo, guardando los no se qué montonada de números de cuenta del banco y los almacena en el disco duro del iPod en forma de imágenes. No contento con esto, los pasa por un OCR y ya tenemos los números de cuenta perfectamente registrados en nuestro portátil… prefiero no hacer comentarios sobre esto.

Son numerosas las películas que, bien utilizados o no, usan al fin un programa real y conocido. El Nmap debe de ser el que se lleva la palma en apariciones cinematográficas, tanto, que sus desarrolladores muestran orgullosos en su página sus numerosas apariciones.

Son muchas las películas que probablemente me olvido de mencionar, pero quiero destacar La Jungla 4.0 (Live Free or Die Hard, 2007) (o cómo puedes salvar el mundo América con un teléfono móvil), en la que al final detectan la IP (supuestamente pública, ya que se está accediendo desde Internet) desde la que se está realizando un ataque, y está es del tipo 10.X.X.X, que como saben es de direccionamiento privado.

Probablemente sabréis de más películas que hablen del tema, bien o mal, pero por encima de todas ellas está una de las películas que más me marcó y no se si es la culpable de que me dedique a esto de las maquinitas, pero seguro que algo influyó. Si amigos, estoy hablando de Juegos de Guerra (War Games, 1983), que con sus virtudes y sus defectos, y a pesar de los años, sigue siendo una de las mejores películas que he visto sobre este tema. Es por eso que fue una de las elegidas para una de las sesiones, que me tocó moderar.