25 de septiembre de 2019

OWASP TOP 10 2017

Nuevamente OWASP nos hace llegar la lista de las más importantes vulnerabilidades en lo referente a desarrollo web en su lista del 2017 Top 10.

OWASP Top 10 2017

Riesgos en Seguridad de Aplicaciones

A1:2017 Inyección

Las fallas de inyección, como SQL, NoSQL, OS o LDAP ocurren cuando se envían datos no
confiables a un intérprete, como parte de un comando o consulta. Los datos dañinos del atacante
pueden engañar al intérprete para que ejecute comandos involuntarios o acceda a los datos sin
la debida autorización.


A2:2017 Pérdida de Autenticación

Las funciones de la aplicación relacionadas a autenticación y gestión de sesiones son
implementadas incorrectamente, permitiendo a los atacantes comprometer usuarios y
contraseñas, token de sesiones, o explotar otras fallas de implementación para asumir la
identidad de otros usuarios (temporal o permanentemente).



A3:2017 Exposición de datos sensible

Muchas aplicaciones web y APIs no protegen adecuadamente datos sensibles, tales como
información financiera, de salud o Información Personalmente Identificable (PII). Los atacantes
pueden robar o modificar estos datos protegidos inadecuadamente para llevar a cabo fraudes
con tarjetas de crédito, robos de identidad u otros delitos. Los datos sensibles requieren métodos
de protección adicionales, como el cifrado en almacenamiento y tránsito.



A4:2017 Entidades Externas XML (XXE)

Muchos procesadores XML antiguos o mal configurados evalúan referencias a entidades
externas en documentos XML. Las entidades externas pueden utilizarse para revelar archivos
internos mediante la URI o archivos internos en servidores no actualizados, escanear puertos de
la LAN, ejecutar código de forma remota y realizar ataques de denegación de servicio (DoS).



A5:2017 Pérdida de Control de Acceso

Las restricciones sobre lo que los usuarios autenticados pueden hacer no se aplican
correctamente. Los atacantes pueden explotar estos defectos para acceder, de forma no
autorizada, a funcionalidades y/o datos, cuentas de otros usuarios, ver archivos sensibles,
modificar datos, cambiar derechos de acceso y permisos, etc.



A6:2017 Configuración de Seguridad Incorrecta

La configuración de seguridad incorrecta es un problema muy común y se debe en parte a
establecer la configuración de forma manual,
ad hoc o por omisión (o directamente por la falta de
configuración). Son ejemplos:
S3 buckets abiertos, cabeceras HTTP mal configuradas, mensajes
de error con contenido sensible, falta de parches y actualizaciones,
frameworks, dependencias y
componentes desactualizados, etc.



A7:2017 Secuencia de Comandos en Sitios Cruzados (XSS)

Los XSS ocurren cuando una aplicación toma datos no confiables y los envía al navegador web
sin una validación y codificación apropiada; o actualiza una página web existente con datos
suministrados por el usuario utilizando una API que ejecuta
JavaScript en el navegador. Permiten
ejecutar comandos en el navegador de la víctima y el atacante puede secuestrar una sesión,
modificar (
defacement) los sitios web, o redireccionar al usuario hacia un sitio malicioso.

A8:2017 Deserialización Insegura

Estos defectos ocurren cuando una aplicación recibe objetos serializados dañinos y estos objetos
pueden ser manipulados o borrados por el atacante para realizar ataques de repetición,
inyecciones o elevar sus privilegios de ejecución. En el peor de los casos, la deserialización
insegura puede conducir a la ejecución remota de código en el servidor.



A9:2017 Componentes con vulnerabilidades conocidas

Los componentes como bibliotecas, frameworks y otros módulos se ejecutan con los mismos
privilegios que la aplicación. Si se explota un componente vulnerable, el ataque puede provocar
una pérdida de datos o tomar el control del servidor. Las aplicaciones y API que utilizan
componentes con vulnerabilidades conocidas pueden debilitar las defensas de las aplicaciones y
permitir diversos ataques e impactos.



A10:2017 Registro y Monitoreo Insuficientes 

El registro y monitoreo insuficiente, junto a la falta de respuesta ante incidentes permiten a los
atacantes mantener el ataque en el tiempo, pivotear a otros sistemas y manipular, extraer o
destruir datos. Los estudios muestran que el tiempo de detección de una brecha de seguridad es
mayor a 200 días, siendo típicamente detectado por terceros en lugar de por procesos internos.


Para obtener mayor información acerca de cada una de estas vulnerabilidades pueden bajar el documento impreso de las mismas en castellano en https://www.owasp.org/images/5/5e/OWASP-Top-10-2017-es.pdf

Espero les sea útil.



Redactado por Mauro Maulini R.

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!

Entradas populares