20 de septiembre de 2019

¿Por qué utilizar Cookies "Seguros"?

Uno de los problemas que presentamos los desarrolladores es el control de los Cookies usados en transacciones seguras. El primer inconveniente que se presenta cuando usamos cookies bajo protocolo SSL o TSL (el conocido HTTPS con la S al final de "secure") es que estos cookies si no tomamos las debidas precauciones en el manejo de los mismos, persisten si el usuario deja la transacción segura para continuar visitando otras áreas de nuestro sitio, lo que convierte su contenido en interceptable.

Otro de los casos que permite revelar las cookies que pasan a través de una conexión segura y que además es muy común, es aquel en el que en una misma página solicitada por HTTPS, solicitamos recursos por simple HTTP, como por ejemplo una imagen en una cabecera que se usa indistintamente en páginas seguras y no seguras. En la cabecera HTTP de la solicitud de dicha imagen el servidor envía todos los cookies del dominio que hace la solicitud en los cuales por supuesto incluye aquellos que se usan para el control de sesión y otras variables de la aplicación "ya no tan segura".

Es importante recordar que el protocolo HTTP es "stateless" o en otras palabras, no maneja estado de sesión, por lo que cada conexión se realiza como si fuera la primera. Precisamente para poder emular un estado de sesión es que las diferentes plataformas de desarrollo utilizan el concepto de un identificador de sesión (session ID), que no es más que un cookie que funciona como identificador de sesión y al cual se asocia un área de memoria en el servidor en la cual se guardan las variables de sesión.

En fin, como ya habrán podido captar, es necesario para la seguridad de la aplicación proteger los cookies, y para ello el protocolo HTTP 1.1 soporta un parámetro para cada cookie conocido como "secure flag" que al ser activado no permite que los cookies con dicho atributos sean transmitidos en conexiones HTTP simple o inseguras.

Este atributo se puede agregar por cada cookie o en general, y cada plataforma conocida lo soporta. Por ejemplo:

En PHP
Coloque en true el parámetro httponly:
setcookie( name, value, expire, path, domain, secure, httponly);

En el php.ini:
session.cookie_secure = on

En JSP /Java Server Pages:

Cookie holaCookie = new Cookie("",text);
holaCookie.setSecure(true);

En ASP.NET
Coloque en el web.config la siguiente línea:

<httpCookies requireSSL="true" /> 

Para hacerlo de forma explícita por cada cookie:

HttpCookie cookie = new HttpCookie("nombre");
cookie.Secure = True;
cookie.Value = "José";

8 de septiembre de 2019

Leer correctamente los datos provenientes del Request

Un "error" muy común de los programadores web en cuanto a la seguridad de sus aplicaciones, es acceder directamente a las variables enviadas desde las solicitudes recibidas desde la colección genéricas Request, como la clase "Request" en ASP o la variable $_REQUEST en PHP:

En ASP:
String nombre = Request["name"];

En PHP:
$nombre = $_REQUEST['name'];

Si bien esta forma de hacerlo es "correcta" lingüisticamente hablando, es bueno recordar que las variables de input tradicionales de una solicitud web suelen llegar por tres diferentes vías: por el método GET, el método POST o a través de cookies. Cuando usamos la clase Request o la variable $_REQUEST según el caso del lenguaje (ASP o PHP) estamos solicitando información en una colección genérica que agrupa las tres opciones (y otras más), y si bien es mucho más fácil y limpio de usar, este método infiere en el error por omisión, de admitir que un dato específico llegue a nuestras páginas por cualquiera de los tres métodos.



El hacker entonces podría perfectamente modificar el valor de un cookie introduciéndolo desde el URL, podría también modificar valores de un formulario que viaja por POST atacándolo desde un simple enlace enviado por e-mail. Esto se debe a que nuestra aplicación al solicitar los datos no diferencia por cual de los tres métodos están siendo enviados. Las implicaciones de poder infectar los cookies del navegador del usuario a través de un URL pueden ser enormes, pero no vamos a detallar esa práctica en este artículo.

Es imperativo, utilizar el método determinado según el acceso por el que debemos recibir los datos y evitar usar el método genérico Request. Ejemplo:

En ASP:
String nombre = Request.QueryString["name"]; // para el método GET
String nombre = Request.Form["name"]; // para el método POST
String nombre = Request.Cookies["name"]; // 

En PHP:
$nombre = $_GET['name'];
$nombre = $_POST['name'];
$nombre = $_COOKIE['name'];

En el lenguaje JSP (Java Server Pages) el problema es aún más grave debido a que el lenguaje no diferencia con el método Request.getParameter("name") si la solicitud es recibida por POST, GET o es un Cookie. En este caso se recomiendan o bien utilizar el método Request.getMethod(), que nos aclara por donde han llegado los datos, simplemente utilizar la tecnología de servlets que si diferencia entre ambos métodos con doGet(request, response) y doPost(request, response).


Redactado por Mauro Maulini R.

4 de septiembre de 2019

Confiar en que el viewState de una página en Asp.NET está cifrado: ¡Error!

Uno de los errores más comunes de seguridad de los programadores de Asp.NET que utilizan "web forms" en sus aplicaciones, es creer que el "viewState" (ese campo oculto que se puede ver en todas las páginas desarrolladas con "web forms" que contiene un cantidad apreciable de caracteres ilegible) está cifrado.

El viewState es un repositorio de información en el que se apoyan los "web forms" para guardar los datos de los diferentes componentes o áreas de una página entre llamada y llamada al servidor. Incluso es accesible desde el código y podemos guardar información allí para usarla en de forma eficiente en nuestras páginas por ejemplo:

ViewState["password"] = thepassword;

Pero no es una buena práctica colocar información sensible como un password en dicho repositorio, debido a que la creencia de que el viewState está cifrado es completamente errónea. El viewState no es cifrado entre viaje y viaje al servidor sino codificado. Si usted conoce algo de criptografía entenderá que la diferencia entre cifrar y codificar es muy obvia, caso contrario permítame explicarle de forma muy resumida un importante detalle a la hora de proteger sus datos: para descodificar solo es necesario conocer el algoritmo en el cual el texto fue codificado, mientras que pare descifrar es necesario conocer una clave de cifrado además del algoritmo y esta no viaja junto al texto cifrado. 

Por lo anterior entenderá que si sabemos el algoritmo con el que el viewState es codificado, solo tenemos que usarlo en reversa para decodificarlo. Y bien ese algoritmo es el conocido Base64. Compruébelo usted mismo introduciendo el viewState de una página Asp.NET en este decodificador de viewState gratuito en línea: http://ignatu.co.uk/ViewStateDecoder.aspx 

Ante este problema tenemos dos soluciones: 
  1. No colocar nunca información delicada en el viewState
  2. Cifrar el viewState o cifrar la información que coloquemos en él.

La primera opción no necesita explicación, la segunda si amerita de algo de información adicional. El viewState, desde la versión de Asp.NET 2.0 en adelante también puede ser cifrado. Usted puede decidir hacerlo en absolutamente todo el sitio web colocando el siguiente atributo en la sección <pages> del archivo web.config:

<pages viewStateEncryptionMode="Always">

Sin embargo hay que tomar en cuenta que el cifrado puede reducir la velocidad de respuesta sobretodo si estamos en un sitio de alto consumo, por lo que podemos también utilizar el cifrado del viewState a nivel de cada página colocando el siguiente atributo en la cabecera <% @ Page >

<% @ Page Language="C#" AutoEventWireup="true" CodeBehind="login1.aspx.cs" ViewStateEncryptionMode="Always" %>

Espero que este truco e información sean de utilidad para los desarrolladores en Asp.NET.

6 de julio de 2017

¿Qué es la autentificación bidireccional y para qué sirve?

No se trata de explicar en este artículo lo mal que la han pasado desde hace ya más de dos o tres años, una innumerable cantidad de instituciones de todo tipo, debido a la proliferación de tipos de ataques "client side" como el Phishing, XSS, Pharming, y otros que no vamos a mencionar por lo largo de la lista, dirigidos específicamente a sus clientes y usuarios. Pero quizás no es tan obvio como lo primero entender que todos estos ataques pudieron haber sido reducidos en un alto porcentaje si se hubieran implementado a tiempo soluciones de autentificación bidireccionales.

¿De qué trata este nuevo término? La idea es muy simple:
No se trata solo de que la aplicación web autentifique y valide que el usuario es quien dice ser, se trata además de que el usuario pueda de igual forma validar y autentificar que la aplicación web sea la que aparentemente es.

Lo extraño de esto es que a pesar de ser una idea básica y muy simple, ha sido implementada en muy pocas aplicaciones y el sufrimiento del usuario ante las técnicas de robo de información y usurpación de atributos de uso y acceso continúa tan vivo como siempre.

Pues bien, para que vean que no es tan compleja la idea y menos su aplicación voy a dar un ejemplo.

Para empezar el banco o institución A, en el proceso de registro de sus usuarios, agrega una simple rutina mediante la cual cada uno de ellos seleccione de una librería de imágenes simples y fáciles de recordar, aquella que más se identifique con él. No quiero complicar esto en este momento, pero el usuario podría inclusive modificar algunos aspectos de la interfaz de la aplicación, "personalizándola", y asociar por ejemplo a la imagen "una frase célebre".

Luego de este proceso el usuario para ingresar a la interfaz privada de la aplicación debe pasar por un sistema de ingreso algo diferente a lo convencional que podemos denominar "doble capa de acceso". Este proceso no significa más que proporcionar los pasos de acceso en dos fases:
  1. En la primera fase el usuario insertará su identificador de usuario (login) y algún otro detalle a discreción del banco A, como por ejemplo el número o nombre de la agencia en la que abrió su primera cuenta. 
  2. Mediante los datos proporcionados en la primera fase por el usuario, el sistema pasa a una segunda fase en la que le muestra a este los cambios realizados a la interfaz y la imagen seleccionada por él en el proceso de registro. Solo si los anteriores corresponden entonces el usuario debe procede a colocar la pieza más crítica de sus datos: su clave de acceso.
Por tanto si no aparecen correctamente la interfaz y la imagen que el usuario seleccionó, seguramente estará ante la presencia de una página falsa y no procederá a insertar el resto de los datos de acceso. Un par de buenos mensajes como: "Si usted no puede ver su imagen de identificación o si nota algún cambio en su interfaz, no coloque su clave de usuario bajo ningún pretexto", son suficientes para que el usuario sepa que hacer en caso de un intento de phishing.

¿Es este proceso demasiado complejo de implementar?

Una de las principales razones que se esgrimen para no hacerlo, es que el proceso de ingreso debe ser realizado en dos etapas o dos páginas, con lo que se hace algo más lento. Esta es en realidad una excusa muy burda, ya que el usuario agradece y con creces este proceso que ya ha sido implementado en algunas instituciones y lo agradece de forma radical, es decir utilizando esas aplicaciones mucho más que otras quizás de mayor funcionalidad pero no tan seguras (al menos en apariencia).

Otro punto a favor de la idea y en contra de la anterior excusa es que este doble proceso puede ser simplificado radicalmente con técnicas actuales como AJAX, que además le ponen el proceso de emulación del sitio al atacante algo más cuesta arriba. No es tan sencillo hacer phishing de un sitio que cambia según lo que agregamos en él y mucho menos si esperamos ver cambios que solo la aplicación y nosotros conocemos.

Además el hecho de que el campo de introducción de la clave aparezca en una segunda fase y solo si los primeros datos coinciden, reduce drásticamente la superficie de ataque hacia los campos más sensibles de una segunda etapa.

Es así de sencillo, pero a pesar de ello las estructuras mentales de los que toman este tipo de decisiones siguen prefiriendo pelear semi-desnudos contra el el phishing y otros flagelos. No me gustaría tener que darle la razón a los hackers cuando mencionan como un hecho que "los code grinders tienen la creatividad de una rana".

Hasta la próxima!

8 de febrero de 2016

OWASP Dirbuster - Escaneando directorios y archivos ocultos de una aplicación web

Uno de los problemas más comunes a la hora de programar es la creencia de que una página o directorio al que no lleva ningún enlace, jamás serán vistos. Pues si esto fuera cierto, lo sería solo en parte, y esa parte dependería de la facultad del programador de escoger nombres complejos y difíciles de adivinar por los expertos en seguridad y por supuesto los atacantes.

La idea de este artículo, es la de encarar al programador con herramientas capacitadas para descubrir la mayor parte del árbol de directorios de nuestra aplicación así como muchas de las rutinas y páginas de esta, por el simple motivo de que todos los programadores usamos casi las mismas herramientas, venimos de una misma corriente de pensamiento o leemos los mismos artículos y vemos las mismas películas y libros. En pocas palabras que debido a que usamos Macromedia Dreamweaver o Visual Studio, nombramos los directorios y archivos de una forma específica.

Este tipo de herramientas trabajan con diccionarios de nombres de archivos y directorios (en varios idiomas) los cuales se prueban solos o con extensiones comunes. Por ejemplo, este tipo de aplicaciones no tardaría prácticamente nada en descubrir un archivo cuyo nombre fuera "admin.zip" en donde un programador incauto podría haber dejado copia de respaldo de todas las rutinas del backoffice de su aplicación. Ejemplos como este hay muchos y algunos espeluznantes, ya que los aciertos no necesariamente son tan sencillos de imaginar como el anterior.

En fin, la intención es que ustedes mismos puedan descubrir cuan vulnerables son esas rutinas administrativas que damos por ocultas o inalcanzables desde la web, y para ello no hay mejor maestro que la experiencia. Y precisamente para que podamos experimentar con nuestras aplicaciones web,  OWASP (quien más podría ser) ha puesto uno de sus proyectos  de seguridad al alcance de todos, y en este caso se trata específicamente del Proyecto "Dirbuster". Disbuster (según palabras de sus creadores) es una aplicación Java multi hilo diseñada para obtener por fuerza bruta los nombres de directorios y archivos en servidores de aplicaciones web.

Puede descargarla en formato comprimido zip en este enlace.

Recuerde, Dirbuster no es más que una aplicación eficiente que nos muestra las posibles fallas de seguridad en la forma en que nombramos nuestras rutinas y directorios, pero cualquier herramienta de análisis de vulnerabilidades seria cuenta con rutinas para el mismo fin y algunas veces suelen ser muy superiores a esta.

Ejecute Dirbuster sobre su aplicación web de forma local, para evitar demoras por problemas de ancho de banda o bloqueo de firewalls, y verá como su forma de nombrar sus archivos y directorios cambiará para siempre.

Hasta la próxima...

Entradas populares