Listado de la etiqueta: owasp

auditar-api

Revisando nuestros servicios: auditar API (parte 1)

Poder ofrecer la información de valor que genera tu empresa de una forma eficiente y segura es tan importante que puede ser el punto de inflexión entre convertirla en un Unicornio o llevarla directamente a la ruina.

En el mundo de hoy, contar con una buena API que permita a terceros consumir tu información te va a permitir extender tu negocio más allá de lo que puedes ofrecer de forma individual. Es habitual conceder acceso a una parte pública de la información, pero otra parte sensible suele estar vinculada a algún contrato, cuota o condiciones particulares.

Una API abierta a terceros te permitirá abrir tu información y servicios a todo tipo de clientes, gestionando hasta dónde quieres que puedan llegar. Sólo tienes que ponerte a desarrollar en tu proceso de integración continua, darle caña a las pruebas unitarias, los test de integración, la documentación y todo lo que tu metodología dicte. Por fin tienes una API de calidad dispuesta a echar humo con miles de clientes y…

…entonces llego yo y te pregunto… ¿has tenido en cuenta la seguridad en el ciclo de vida de tu API?

Tu respuesta tiene una alta probabilidad de ser «ehhh…. no!». Lo normal es que sea así y que se hayan cometido errores de desarrollo que impliquen vulnerabilidades en nuestra API que puedan impactar en nuestro producto.

¿Como incorporo la seguridad a mi API?

api_security

Si no has empezado a desarrollarla, entonces te recomiendo que tengas en cuenta algún modelo como «Microsoft Security Development Lifecycle» (echando un vistazo aquí, aquí o aquí, aunque hablaremos de esto en breve) y lo hagas bien desde el principio.

Si ya tienes tu API funcionando, en la próxima entrada realizaremos una pequeña prueba que te puede ayudar a evaluar su seguridad.

En cualquier caso, deberías tener en cuenta siempre estos checks básicos:

1) Fase de Autenticación:

  • Habilita tu API únicamente con SSL, todos los accesos debería ser https. Prohibe http o dale un uso meramente informativo.
  • Nunca envíes usuarios, contraseñas, tokens… en la url.

2) Fase de Autorización:

  • Pon especial atención en el escalado de privilegios tanto en horizontal como en vertical.
  • Acentúa los controles en las peticiones que actualicen o eliminen información.
  • Utiliza roles para administrar permisos de tus usuarios.
  • Protege al máximo las funcionalidades destinadas a usuarios administrativos.

3) Gestión de sesión:

  • Habilita un tiempo máximo de sesión (timeout).
  • Asegúrate de tener medidas para invalidar tokens si es necesario.

4) Validación de entradas:

  • Los ataques web habituales pueden afectar a tu API, así que pon atención en los conocidos ataques de injección, xss…

5) Codificación de salidas:

  • Revisa bien la estructura de tu salida json, xml,…
  • Inserta cabeceras de seguridad acordes al uso que se le va a dar a tu API.

Empieza por echar un vistazo a estas recomendaciones. En la próxima entrada seguiremos viendo detalles para tener tu API lo más segura posible. ¿Te lo vas a perder?

de-charleta

De Charleta: “Mobile App Pentesting en Primera Persona” (Gustavo Sorondo)

Hace poco se celebró la DragonJar Security Conference 2.016, así que hoy recomendamos esta interesante charla en la que Gustavo Sorondo (Puky) nos cuenta un proceso de pentesting sobre una app móvil.

Gustavo Sorondo es CTO de «Cinta Infinita – Information Security». En su carrera profesional ha trabajado en más de 100 proyectos relacionados a la seguridad de la información en 6 paises, y ha dictado cursos de Penetration Testing, Seguridad en Aplicaciones Web, Seguridad Wireless y Testing de Mobile Apps. También ha dado charlas y workshops en conferencias de seguridad como ekoparty, OWASP Latam Tours, Segurinfo, RISECON y PampaSeg.

DragonJar Security Conference 2.016.

Español.

auditoria-de-codigo

Auditoría de código: algo necesario pero que nunca hacemos (parte 3)

Ha pasado un poco de tiempo desde que empezamos con esta serie de entradas dedicadas a la auditoría de código, pero vamos de nuevo con el último post de la serie.

En la primera parte, hicimos una introducción a la tarea y vimos cómo se trata de algo que cada vez cobra más importancia. En la segunda parte planteamos los primeros pasos, así como la forma en la que organizar el equipo y poder repartir tareas. ¿Seguimos?

Separa “lo blanco” de “lo de color”

Cuando nos pongamos manos a la obra, debemos tener en cuenta que casi siempre podremos hacer auditoría estática (leyendo código) y dinámica (ejecuciones en entorno de prueba). Ser capaz de separar qué parte corresponde a cada caso será vital para acortar tiempos y obtener un resultado positivo.

Para poder hacerlo, nos basaremos en la documentación obtenida en la fase anterior y en una clara enumeración de tecnologías y sistemas. Teniendo toda la información sobre la mesa, podremos otorgar pesos de forma que:

Código candidato a auditoría estática:

  • Partes desarrolladas hace mucho tiempo.
  • Partes generadas de forma automática (sobre plataforma “insegura”).
  • Algoritmos “a medida” y complejos.
  • Partes sin documentar.
  • Zonas de acceso anónimo.
  • Valores y configuración por defecto.
  • Desarrollo en ensamblador.

Código candidato a auditoría dinámica:

  • Partes desarrolladas hace poco tiempo.
  • Partes generadas de forma automática (sobre plataforma “segura”).
  • Algoritmos conocidos o sencillos
  • Partes bien documentadas.
  • Zonas de acceso bajo autenticación de usuario.

Con esta separación podremos realizar varias iteraciones con varios niveles de búsqueda, yendo desde lo más automático hasta lo más manual.

¡Briconsejo!

Muchas veces, la sencilla búsqueda de palabras clave te puede ofrecer una buena lista de cosas a revisar con lupa…

Cosas como pass, root, secret, key, admin, user, db, bug, fix, todo,… son candidatas a tener en cuenta. ¡No olvides hacerte con un buen diccionario de ellas!

¿Y qué podemos encontrar?

Para este tipo de auditorías, suelo revisar el conocido OWASP top 10 y derivados. Te recomiendo que eches un vistazo a estos enlaces de interés:

Ahí podrás ver cómo detectar y mitigar cosas tan habituales como:

A) Funciones inseguras o prohibidas: a menudo te puedes encontrar que esa función que se está usando, la documentación no la recomienda (¿para qué puñetas está?… por compatibilidad..).

void VerificarID(char *usuarioID){
   char buf[10];
   strcpy(buf, usuarioID);
}

El uso de la función strcpy está desaconsejado por problemas derivados de ataques buffer overflow.

 

B) Referencia insegura directa a objetos (Directory transversal): exponer rutas completas de acceso a ficheros puede dejar el camino abierto para acceder a otros lugares que no estaban planteados inicialmente.

public class CrystalImageHandler : WebControl {
   private string tmpdir = null;
   
   protected override void Render(HtmlTextWriter writer) {
      string filepath;
      string dynamicImage = (string)Context.Request.QueryString.Get("dynamicimage");

      if (tmpdir == null) {
         tmpdir = ViewerGlobal.GetImageDirectory();
      }

      filePath = tmpdir + dynamicImage; FileStream imagestream = new FileStream (filePath, FileMode.Open, FileAccess.Read); 

      ... 
 
      File.Delete (filePath);
   }
}

Esto permite a un atacante hacer algo como: http://foo.bar/crystalreportviewers/crystalimagehandler.aspx?dynamicimage=..\..\..\..\..\mydocuments\private\passwords.txt

 

C) Inyección de comandos sql (SQL Injection): cualquier entrada de datos de usuario no filtrada puede convertirse en una puerta para un atacante. Utilizar esa entrada para hacer que se ejecuten determinados comandos es hoy (y desde hace años) uno de los principales problemas de seguridad.

String query = "SELECT * FROM accounts WHERE custID='" + request.getParameter("id") +"'";

Un atacante puede insertar algo como http://example.com/app/accountView?id=’ or ‘1’=’1 y obtener todas las cuentas de usuario.

 

D) Secuencia de comandos en sitios cruzados (Cross-Site Scripting o XSS): cuando se muestra el contenido del usuario por pantalla sin pasar por ningún filtro, se pueden llegar a ejecutar comandos no deseados.

echo $_REQUEST['userinput'];

Un atacante puede introducir como entrada algo tipo <script>alert(«XSS»)</script> y obtener un popup por pantalla que le daría paso a probar cantidad de maldades.

 

Pero no nos olvidemos de otros clásicos derivados de la constante de inutilidad como:

E) Código oculto: partes de código que no deberían estar ahí ni hacer lo que hacen (backdoors).

int main(){

    int x;
    double fact=1;

    printf("Escriba el número: ");
    scanf("%i",&x);

    if(x == -1) {
       OpenBackdoor();
    }

    while(x>1) fact*=x--;

    printf("Factorial =%lf",fact);
}

Será complicado encontrar y podría superar un análisis automático.

 

F) Mala gestión de errores: mostrar mensajes de error con todo lujo de detalles por pantalla o no gestionar determinadas excepciones son prácticas habituales.

try{
   SaveToDB();
}
catch(Exception ex){
   // Esto no falla nunca, no hay problema.
}

¿Eres de los que haces pruebas en producción?

 

G) Contraseñas en código: para no tener que tirar de BD, a veces incluso se meten contraseñas “a fuego”, algo que se puede obtener con un sencillo decompilador.

String user_pass = Request.Form("UserPass");

String pass = "User_Pass_123!";

if(user_pass.Equals(pass)){
   OpenConnection();
}

No pienses que nadie va a mirar tu código, dejar ahí información no es para nada una buena práctica.

 

Por supuesto, debemos llevar un seguimiento de todas las evidencias y errores que vayamos encontrando mediante el uso de nuestras herramientas favoritas de gestión de bugs o documentación, teniendo en cuenta:

  • Debemos destinar un tiempo diario para escribir resultados.
  • Debemos guardar capturas de pantalla y referencias de todo lo relevante, tanto si son resultados satisfactorios como si no lo son.
  • Debemos facilitar la continuidad del trabajo para otros auditores.

Una vez tengamos documentado todo, tendremos que generar dos informes que hablarán de lo mismo, pero con dos enfoques diferentes.

El informe técnico

informe-tecnico

Se trata de un informe de alto detalle en el que mostraremos todo lo que se ha encontrado. Está realizado por informáticos y va a ser revisado por informáticos, no tengas miedo a usar lenguaje técnico.

Y, aunque parezca una chorrada, permíteme que te recuerde que no debemos recrearnos en errores ajenos. La serenidad, elegancia y diplomacia son factores básicos.

El informe ejecutivo

informe-ejecutivo

Se trata de un informe de bajo detalle en el que mostraremos, de una forma ágil, el resultado de la auditoría. Debe alejarse de tecnicismos, no deberás hablar de herramientas o técnicas.

Cuanto más expresivo, mejor, no tengas miedo a usar cifras, iconos y ser cuantificable. El objetivo es que sea rápido de leer por personas de dirección que no tienen tiempo para entrar en demasiado detalle.

Sobre todo, ten en cuenta que el informe es el reflejo de una auditoría y permite medir la calidad de la misma. Una auditoría puede fracasar por un mal informe.

Y hasta aquí la entrada de hoy, espero que los consejos que te he dado sean de utilidad para tus auditorías de código. Si ves algún error, no estás de acuerdo con lo que cuento o quieres hacer alguna aportación, no dudes en pasarte por los comentarios.