9 de julio de 2014

Cómo implementar el encabezado HTTP Strict Transport Security en código

Si el video de OWASP del anterior post sobre HSTS (HTTP Strict Transport Security) los dejó con algo de espectativas acerca de la implementación del encabezado de HTTP para el uso estricto de HTTPS, entonces lo que viene a continuación les interesa.
Si bien se puede implementar el encabezado a nivel de servicio web agregando en la configuración de las diferentes plataformas (Apache, IIS, nginx y otros) un "header", a veces es mucho más práctico agregar la cabecera directamente a nivel de aplicación o en las rutinas específicamente sensibles.
Cómo el vídeo no nos muestra el código para ello a continuación algunos ejemplos en diferentes lenguajes y/o plataformas:

Implementación en PHP.
// Usar HTTP Strict Transport Security para forzar al cliente a usar 
// conexiones seguras

$use_sts = true;
 
// iis sets HTTPS to 'off' for non-SSL requests
if ($use_sts && isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
    header('Strict-Transport-Security: max-age=31536000');
} elseif ($use_sts) {
    header('Location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], true, 301);
    // we are in cleartext at the moment, prevent further execution and output
    die();
}  
Implementación en Perl CGI.
# Usar HTTP Strict Transport Security para forzar al cliente a usar
# conexiones seguras
use CGI;
use URI;
 
my $q   = new CGI;
my $url = URI->new($cgi->request_uri)
my $use_sts = 1;
 
if ($use_sts and $url->scheme eq 'https') {
    print $q->header('Strict-Transport-Security' => 'max-age=31536000'); 
} elsif ($use_sts) {
    $url->scheme('https');
    print $q->redirect(status => 301, location => $url);
}  
Implementación en Ruby on Rails.
class ApplicationController < ActionController::Base
  before_filter :ensure_proper_protocol
 
private
  def ensure_proper_protocol
    if request.ssl?
      response.headers['Strict-Transport-Security'] = 'max-age=31536000'
    else
      redirect_to "https://" + request.host + request.request_uri, :status => 301
    end
  end
end  
Implementación en C# / ASP.NET. Código en archivo global.asax
// Usar HTTP Strict Transport Security para forzar al cliente a usar 
// conexiones seguras
protected void Application_BeginRequest() { switch (Request.Url.Scheme) { case "https": Response.AddHeader("Strict-Transport-Security", "max-age=31536000"); break; case "http": var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery; Response.Status = "301 Moved Permanently"; Response.AddHeader("Location", path); break; } }  
Implementación en ColdFusion Markup Language (CFML).
<!--- Usar HTTP Strict Transport Security para forzar al cliente a usar
conexiones seguras --->
<cfset use_sts = true>
 
<cfif use_sts is "True">
    <cfif cgi.https is "on"> 
        <cfheader name="Strict-Transport-Security" value="max-age=31536000">
    <cfelse> 
        <cfheader statuscode="301" statustext="Moved permanently">
        <cfheader name="Location" value="https://" + CGI.SERVER_NAME + CGI.SCRIPT_NAME + CGI.QUERY_STRING>
    </cfif>
</cfif>  
Implementación en JavaServer Pages (JSP) o Java Servlets.
// Usar HTTP Strict Transport Security para forzar al cliente a usar 
// conexiones seguras
boolean use_sts = true; if(use_sts) { if(request.getScheme().equals("https")) { // Send HSTS header response.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubdomains"); } else { // Redirect to HTTPS response.setStatus(301); String url = "https://" + request.getServerName(); if(request.getPathInfo() != null) { url = url + "/" + request.getPathInfo(); } if(request.getQueryString() != null && request.getQueryString().length() > 0) { url = url + "?" + request.getQueryString(); } response.setHeader("Location", url); } }

Espero les sea suficientemente útil y como podrán apreciar no es nada complicado.

12 de agosto de 2013

Las aplicaciones móviles son fáciles de "decomplilar"

Todos los programadores sabemos a ciencia cierta que las aplicaciones son de una manera u otra "decompilables", es decir podemos obtener con las herramientas adecuadas el código fuente de la aplicación para alterarlo y/o modificarlo (y si no lo sabemos es hora de despertar). Sin embargo cuando una aplicación se encuentra en formato binario el proceso de ingeniería de reverso es mucho más complejo, pero no es este el caso cuando hablamos de aplicaciones móviles desarrolladas en lenguajes como Java o .NET que en realidad no se encuentran en código binario sino en formato intermedio conocidas como "bytecodes" en el caso de Java e "intermediate language (IL)" en el caso de .NET

En el caso de iOS, decompilar las aplicaciones es algo más complejo ya que son necesarios decompiladores costosos y conocimiento avanzado de las técnicas, sin embargo tampoco es un trabajo imposible de realizar.

Si dudan de lo anterior, solo necesitan seguir este enlace http://www.youtube.com/watch?v=3tioug10tuo  que los llevará a un video de cómo decompilar aplicaciones para Android.

Por lo tanto es muy importante entender que debemos ser más eficientes y cautos a la hora de hablar de seguridad en el caso de las aplicaciones móviles, ya que ponemos en riesgo nuestro trabajo (lo cual sería lo menos preocupante) así como la "lógica de negocio" de la empresa para la que desarrollamos la aplicación o lo que es peor aún los datos confidenciales de los usuarios que la utilicen.

Hay una buena cantidad de consejos que deberemos tomar en cuenta mientras desarrollamos aplicaciones móviles, pero quizás el más importante de todos pudiera ser si vamos a desarrollar aplicaciones seguras, no dejar jamás datos específicos "hard coded" dentro de la aplicación. Hablando en lenguaje más simple, no debemos jamás dejar una clave de cifrado, una cadena de conexión a un servidor o base de datos o un algoritmo de negocios en texto plano en nuestro código.

Para evitar lo anterior, todo dato sensible debe ser cifrado y la clave de cifrado debe ser proporcionada por alguna constante del entorno del dispositivo que se mantenga permanentemente pero que sea diferente en otros dispositivos. Por tanto si un amigo de lo ajeno obtiene nuestro código, le será mucho más difícil obtener nuestros datos o lo de nuestros usuarios, ya que cada usuario tendrá una clave de cifrado única.

Lo anterior haría más difícil la obtención de la clave pero no evitaría que el atacante la obtuviera, sin embargo debería repetir un procedimiento complejo para cada usuario o tener acceso directo al dispositivo de cada uno de ellos, lo que reduce drásticamente la superficie de ataque.

Muchos otros son los consejos de seguridad para aplicaciones móviles, como por ejemplo obtener un buen ofuscador de código si realmente se considera de alta prioridad la seguridad, como en el caso de aplicaciones bancarias o de pago. En próximos artículos hablaremos más sobre esto...

Hasta la próxima...

9 de octubre de 2012

OWASP Appsec Tutorial Series - Episodio 4: Seguridad de Transporte Estricta

El siguiente episodio de la serie OWASP Tutorial Appsec describe la importancia de utilizar HTTPS para toda la comunicación sensible, y cómo el encabezado HTTP Strict Transport Security (estricta seguridad de transporte) se puede utilizar para garantizar una mayor seguridad, mediante la transformación de todos los enlaces HTTP a HTTPS automáticamente en el navegador.

Espero les sea útil...
Hasta la Próxima.


8 de octubre de 2012

Comenzando con Seguridad para ASP.NET

Recientemente llegó a mis manos un libro muy interesante llamado "Beginnig ASP.NET Security" de la serie de libros de WROX Programmer to Programmer, que no puedo dudar ni por un segundo en recomendarles en este artículo.

A pesar de ser un libro para programadores, su lenguaje es bastante claro en los primeros capítulos para que cualquier programador de la excelente plataforma de desarrollo web de Microsoft, pueda entender sin inconvenientes todos los "intrigulis" de la seguridad web.

En este libro encontrará, como proteger sus aplicaciones en ASP.NET basándose en el documento OWASP TOP 10, que es el documento creado por la Open Web Application Security Proyect para implantar un estándar de referencia acerca de los 10 tipos más comunes de vulnerabilidades detectadas en aplicaciones web. Por tanto el libro toca cada una de las anteriores y muestra las diferentes formas de proteger las aplicaciones, y además permite seguir paso a paso los métodos de cifrado mas eficientes utilizándolos desde la plataforma .NET para proteger los datos de nuestros usuarios.

También maneja un amplio capítulo acerca de la seguridad en el IIS (Internet Information Server) que es la plataforma de servicios con la que se ofrece lógicamente ASP.NET (entre otros). Además uno de sus más extensos capítulos está dedicado a la seguridad de Web Services, bajo WCF (Windows Communication Foundation) a través de RIA, SOAP y otros protocolos de servicios web. Por último ofrece todo un capítulo que explica como adaptar los procesos de seguridad básicos al ASP.NET MVC (Model View Controller).

El libro está actualizado a la plataforma de ASP.NET 4, pero sus capítulos están adaptados para ser utilizados en versiones anteriores.

Es mi recomendación que este libro se convierta en una referencia de seguridad obligada para todo proyecto en ASP.NET.

Hasta al Próxima...

8 de julio de 2012

¿Cómo mejorar el "hashing" de las claves de acceso sin molestar al usuario?

Siempre hemos mencionado que definitivamente "No debemos guardar claves de acceso en nuestras bases de datos". Sin embargo la técnica intermedia de guardar el HASH de dichas claves hasta ahora ha sido una solución interesante. Aún así, ya tampoco es muy seguro utilizar esta técnica de forma simple debido a los Ataques por Diccionarios de HASH y los Raibow Tables.

También es necesario acotar se ha demostrado que ciertos tipos de hash como el MD5 presentan conflictos de colisiones, por los cuales los certificados SSL que utilizaban este hash quedaron fuera de circulación debido a que podían ser emulados buscando una colisión específica cualquiera que aunque no representara el certificado original, permitiera emularlo.

Por lo tanto la anterior debilidad del MD5 no solo es válida para los certificados SSL sino para cualquier sistema que lo utilice y por consecuencia para cualquier proceso de validación de clave que se base en este algoritmo. Sin embargo las técnicas de "salting" basadas en agregar una cadena específica a la clave de acceso antes de calcular el hash todavía pueden "salvarle el pellejo" en caso de un ataque, ya que aunque el atacante pueda encontrar un texto que colisione con el md5, este no pasaría la validación ya que al agregarle el "salt key" y calcular el hash este cambiaría nuevamente.

Mi recomendación es que definitivamente no cuente con el md5 en sus desarrollos a futuro y trate de reemplazarlo en los existentes. Sin embargo cuando ya usted posee una gran cantidad de usuarios es difícil cambiar de algoritmo de hashing sin obligarlos a cambiar de clave. Usted no puede cambiar el algoritmo simplemente ya que no posee (al menos no debería) las claves originales sobre las que realizar el cálculo del nuevo hash.

Para esto hay un remedio muy eficiente que se basa en utilizar la técnica de "salting" aplicándola al hash que ya posee y calculando un nuevo hash (preferiblemente no md5) sobre el resultado.  

Ejemplo:
  • Imaginemos que el usuario utilizó una clave como por ejemplo: Hey@you123
  • Usted no conoce dicha clave pero posee el hash MD5 de la misma que es lo que hasta ahora ha utilizado para validar el ingreso del usuario a su sistema: 27f97cb40faf0a16e09dde2a1c2b25b8
  • Agréguele una palabra (salt key) a dicho hash como por ejemplo:  MySaltKey28
  • La cadena resultante sería en este caso:  27f97cb40faf0a16e09dde2a1c2b25b8MySaltKey28
  • Ahora calcule un hash nuevamente con el algoritmo que prefiera (en este caso por ejemplo hemos utilizado SHA1):
    4cd80c13b53a136f62732c6a1e3f88200192edbf
  • Guarde el nuevo resultado en otro campo y deshágase de todo vestigio del viejo hash md5.
Recuerde que cada vez que un usuario quiera validar usted deberá repetir el proceso empezando por calcular el MD5, agregar el "salt key" y calcular el SHA1, aunque esto no debiera ser nada complejo si usted prepara una rutina eficiente que siga los pasos requeridos.

Usted habrá utilizado dos técnicas de hashing que juntas pueden garantizar la seguridad de sus usuarios:  "Hash Salting" e "Interacción entre diferentes tipos de hash". De esta forma si el nuevo hash cayera en manos indebidas ya no podría obtenerse una colisión ni utilizarse un ataque por diccionario.

Usted puede además complicar este proceso tanto como lo desee agregando más interacciones o cálculos recursivos de hash, pero deberá pensar en el tiempo y recursos que podría tomar un cálculo demasiado complejo en relación a la cantidad de usuarios y cantidad de validaciones que requiera.

Hasta la próxima...

Entradas populares