Este documento ofrece consejos prácticos para crear aplicaciones seguras. Explica que los errores de seguridad pueden ser muy costosos y que factores como la validación de datos, el uso de criptografía, el análisis de código y las pruebas son importantes. También destaca la necesidad de procesos de seguridad integrales en todo el ciclo de vida del desarrollo de software.
3. Seguridad en software
Los errores en software pueden llegar a ser muy costosos:
¿Qué tal los errores de seguridad?
Bug en software de
sistema antibloqueo de
frenos le costó a Toyota
un aproximadamente 3
billones de dólares
americanos. (2009).
Bug en software de
trading le costó a
Knight Capital Group
Inc. cerca de 400
millones de dólares
americanos.(2012).
4. Costo de un bug de
seguridad en software
En etapa de diseño:
En etapa de pruebas (QA):
En producción:
+
$10000 USD
para arriba
$1500 USD
Impacto al negocio
$100 USD
5. • Es más rápido.
• Es más barato.
• No realizo ejercicios de revisión de
código.
• Porque afecta la experiencia de
usuario.
• No conozco de esos temas.
• Tengo appliances de seguridad que
me protegen.
• No tengo procesos que involucren
la seguridad.
• Es más difícil …
¿Por qué
hacemos
aplicaciones
inseguras?
6. El factor humano
“Think about how
stupid the average
person is, and
then realize that
half of them are
stupider than that”
7. El factor humano
Hecho: Somos humanos, nos
equivocamos... frecuentemente.
NASA olvida convertir
unidades y ocasiona que el
Climate Orbiter se pierda en
el espacio. (1998)
Recordemos brevemente eventos del pasado:
El error del doble gotofail
de Apple que permite
realizar ataques de MiTM a
millones de usuarios.
(2014)
10. ¿Qué tanto
importa
el lenguaje?
Existen mecanismos de
seguridad implementados en
lenguajes que deben
considerarse en base a los
requerimientos de cada
proyecto:
● Type-safe object oriented
programming
● Safe memory management
● Safe object construction
● Smart pointers/Safe
pointers
● Entre otros...
11. ¿Es culpa del lenguaje?
Revisemos estadísticas de
vulnerabilidades existentes
en diferentes lenguajes de
programación.
¿Qué nos dicen estos números?
12. PHP: 406 vulnerabilidades entre 2000-2015
http://www.cvedetails.com/product/128/PHP-PHP.html?vendor_id=74
13. Ruby: 44 vulnerabilidades entre 2007-2014
http://www.cvedetails.com/product/12215/Ruby-lang-Ruby.html?vendor_id=7252
14. ASP.NET: 10 vulnerabilidades entre 2003-
2010
http://www.cvedetails.com/product/3091/Microsoft-Asp.net.html?vendor_id=26
18. 1. Muchos productos son una
combinación de lenguajes
y tecnologías.
2. Bases de datos como CVE
no tienen registro de todas
las vulnerabilidades.
3. A veces también los
frameworks de desarrollo
tienen vulnerabilidades.
4. Existen muchas más
vulnerabilidades en
implementaciones (no
lenguaje).
Los números no necesariamente
reflejan la realidad:
000101010111011100000011111101010
101000001010101010101010101010100
000001010101110111000000111111010
101010000010101010101010101010101
000000010101011101110000001111110
101010100000101010101010101000010
101011101110000001111110101010100
000101010101010101010101010000000
101010111011100000011111101010101
¿Importa el
lenguaje de
programación?
000101010111011100000011111101010
101000001010101010101010101010100
000001010101110111000000111111010
101010000010101010101010101010101
000000010101011101110000001111110
101010100000101010101010101010101
010000000101010111011100000011111
19. Seguridad en software web y movil
Existen controles de seguridad que hacen más
robustas a nuestras aplicaciones:
• Autenticación
• Autorización
• Manejo de sesiones
• Validación de datos
• Auditoría y bitácoras
• Criptografía
• Ambiente de desarrollo
• Canales de comunicación
• Almacenamiento seguro
¿En qué nos estamos equivocando?
23. No confíes en extraños
(*) http://www.websec.mx/blog/ver/inseguridad-datos-sesion-codeigniter
● Malos consejos de
seguridad hasta
en sitios oficiales
de proyectos.
● Un ejemplo, el popular
framework Codeigniter
distribuye la siguiente
configuración por
default. >>
24.
25.
26.
27. Buenas prácticas
Siempre revisen
lo que instalan.
No confien en
configuraciones
default.
Hashes de verificación de integridad
de archivos críticos de la aplicación.
Algún HIDS, solución casera en Bash,
tripwire, etc.
No sigan guías sin
cuestionar las
prácticas de
seguridad.
31. Utilizar frameworks
no garantiza
seguridad
Existen muchas
implementaciones inseguras. De
nuevo no es el framework, es la
implementación.
● oAuth es un
framework de
autorización.
● OpenID es un
framework de
autenticación.
33. ¿Como
es una buena
implementación?
Una buena implementación de
autenticación y autorización:
● Registra todas las actividades de
los usuarios sin revelar
información privada.
● Verifica el origen, validez y
expiración de sesiones.
● Genera alertas en caso de
actividad sospechosa (Cuenta
bloqueada por superar intentos
de inicio de sesión, etc.).
● Tiene mecanismo de protección
contra ataques de fuerza bruta.
● 2 factor auth (Si es requerida).
● Autoriza el acceso a cada
recurso solicitado.
36. Todos sabemos que debemos
validar datos y sin embargo las
mismas vulnerabilidades siguen
existiendo.
Validación de datos
La regla es muy simple:
NO CONFIEN EN NINGÚN DATO DE
ENTRADA MANIPULABLE
37. ● No usen listas negras.
● Usen los mecanismos de validación
disponibles en los frameworks pero no
dependan de ellos completamente.
● Prueben sus expresiones regulares.
● Monitoreen todos los puntos de entrada
Buenas prácticas
38.
39. [20/01/2015 01:00:05] Fallo
de inicio de sesion con usuario
‘admin’ y password
‘Administrad0r20’
[20/01/2015 01:00:09] Fallo
de inicio de sesion con usuario
‘admin’ y password
‘Administrad0r201’
[20/01/2015 01:00:15] Inicio
de sesion exitosa de usuario
‘admin’
Guardamos
información
de más
+
40. O no
guardamos
nada
[20/01/2015 04:00:05] La
aplicación tuvo un error.
Origen de conexión: 127.0.0.1
[20/01/2015 04:00:09] La
aplicación tuvo un error.
Origen de conexión: 127.0.0.1
[20/01/2015 04:00:15] La
aplicación tuvo un error.
Origen de conexión: 127.0.0.1
41. (IN)seguridad en bitácoras
Muchas veces los desarrolladores
no piensan en los riesgos:
● Cualquier aplicación puede
acceder a las bitácoras del
sistema Logcat (Android).
● Bitácoras comprometidas a
través de vulnerabilidades en
aplicaciones web.
Aplicaciones móviles y web
revelan información sensible en
bitácoras:
● URLs de servicios,
endpoints, APIs, etc.
● Credenciales de acceso a
servicio.
● Nombres de variables de
datos de entrada.
● Datos de usuario.
● Trazas de error.
42. • Almacenar las bitácoras en otro dispositivo
diferente de donde se corre la aplicación.
• Almacenar la información mínima necesaria para
diagnosticar un problema. Incluir funcionalidad
para generar trazas más completas.
• Comprobar que las bitácoras están siendo
registradas correctamente.
• Desarrollar agente que envíe la información al
corelacionador de bitácoras de la empresa (Si lo
tienen).
Buenas prácticas
43. Crypto
La criptografía es difícil.
Si no han estudiado el tema,
¡No escriban sus propias
funciones criptográficas!
Dejen ese trabajo a los
EXPERTOS.
48. Lo que sí debe saber un desarrollador
sobre criptografía como mínimo
● Diferencia entre criptografía asimetrica y
simetrica.
● Diferencia entre métodos de cifrado.
● Uso de políticas seguras para contraseñas y
passphrases.
● Estándares modernos de criptografía.
www.keylength.com
● Conocer las librerías robustas de criptografía
disponibles para su ambiente de desarrollo.
49. Hecho: La mayoría de aplicaciones inseguras
no realizaron ejercicios de revisión de
código fuente.
50. Software Testing
Tenemos hasta un día
internacional dedicado
al debugging...
Literalmente encontraron un
bicho pegado a la hoja de un
programa.
Premio: ¿Qué fecha es el día
internacional de debugging?
52. Programas donde se ofrecen recompensas por encontrar bugs de seguridad.
Algunas empresas que han implementado este programa exitosamente:
● Google
● Facebook
● Microsoft
● Otros muy interesantes como Internet Bug Bounty
(https://internetbugbounty.org) dan recompensa por encontrar bugs en
productos como Apache, Ruby, Python, PHP, entre otros).
Programas bug bounty
¿Podrían implementarlo en su
empresa o lugar de trabajo?
53. Software testing
Unit testing aunque sea muy
tedioso es una herramienta
invaluable para construir
software seguro.
Necesitamos integrar a
nuestro SDLC ejercicios de
análisis estático y dinámico
54. Integration testing
Si automatizamos los procesos de ‘integration testing’
lograremos detectar muchos problemas.
Por ejemplo Jenkins puede ser utilizado en proyectos hechos
en Java, ASP.NET, Perl y Python.
55. Software
fuzzing
Automatizar pruebas al software
con datos de entrada aleatorios y
mal formados. El objetivo es
analizar el comportamiento de la
aplicación bajo diferentes datos de
entrada mal formados.
Algunos fuzzers públicos:
● spike
● antiparser
● Afl
● Sulley
● Melkor
!Para mejores resultados
construyan los suyos!
57. Clang
Analizador estático de código para
C/C++/Obj-C
● Encontrando heartbleed con Clang:
http://blog.trailofbits.com/2014/04/27/usi
ng-static-analysis-and-clang-to-find-
heartbleed/
Otros proyectos interesantes basados en
Clang:
● Xsecurity
https://github.com/XSecurity/Xsecurity
Integración con Xcode para detectar
vulnerabilidades en aplicaciones iOS.
● Infer
https://github.com/facebook/infer
Analizador estatico de código para
aplicaciones mobiles Android e iOS.
58.
59. Infer
Analizador estático de código
desarrollado por Facebook para
Java, C y Obj-C.
Descarga:
https://github.com/facebook/infer
62. Grep para
analizar
código
Grep es nuestro amigo. Por ejemplo podríamos
utilizar algo como:
$grep –R –n –A3 –B3 –i
’$_GET|$_POST’ .
En ambientes Windows: File
Locator Lite
63. Análisis de
código gratis
Websec tiene una base de datos con listas de nombres
de funciones ‘peligrosas’ divididas por lenguaje de
programación (JAVA, RUBY, PHP, Python)
InsecureProgrammingDB
https://github.com/cldrn/InsecureProgrammingDB
65. Otras herramientas
● Navegadores de código fuente.
● Seguridad de binarios
Ya hablamos de herramientas, pero ¿qué tal los
procesos?
66. ¿Por qué
hacemos
aplicaciones
inseguras?
La ausencia de procesos
de negocio que
respalden la seguridad
siempre llevará a la
creación de código
inseguro.
La seguridad debe ser
planeada desde el principio
e integrada en la
arquitectura de la
aplicación.
67. Thread
modeling
Método para analizar la
seguridad de una aplicación que
permite identificar, evaluar y
mitigar los riesgos relacionados
con la aplicación.
68. Retos
al realizar
thread
modeling
● No se conocen a fondo los
procesos involucrados.
● No se conocen los riesgos.
● Difícil asignar importancia si
se desconoce el nivel de
explotación requerido.
69. Thread modeling en tu organización
1. Entiende tu aplicación.
2. Identifica las amenazas.
3. Desarrolla las medidas de
protección y mitigaciones.
70. Seguridad en el ciclo de vida
de desarrollo de software
● Evaluar el riesgo de nuevas aplicaciones.
● Investigar requerimientos necesarios para tratar la
información según su sensibilidad.
● Elaborar una guía de buenas prácticas a las que
todos deben apegarse.
● Periódicamente evalúa y actualiza esa guía de
buenas prácticas.
● Entrena a los programadores a tomar talleres
técnicos de programación segura en el entorno de
trabajo.
● Incluye aspectos de seguridad en evaluaciones de
QA.
71. Seguridad en el ciclo de vida
de desarrollo de software
Herramientas pueden ayudar pero
necesitan a una persona con
conocimientos en seguridad informática
en el equipo para validación.
Es importante no usar solo una
herramienta.
72. REQUERIMIENTOS:
Documentar/Identificar los requerimientos de seguridad del proyecto.
Análisis de riesgo.
DISEÑO:
Thread modeling.
DESARROLLO:
Implementar mejores prácticas.
Análisis estático de código.
TESTING:
Análisis dinámico de la aplicación.
Fuzzing.
Análisis de vulnerabilidades.
DEPLOYMENT:
Revisión de configuración de seguridad de aplicación y servidor.
73. Seguridad
en el
entorno de
desarrollo
La seguridad comienza desde nuestras
casas. Es decir, nuestros ambientes de
desarrollo.
Auditando las llaves públicas de todos
los usuarios de Github:
https://blog.benjojo.co.uk/post/auditing
-github-users-keys
74. ¿Qué aprendimos hoy?
Si quieren crear aplicaciones seguras deben:
● No confien en extraños.
● No confien en ningún dato de entrada manipulable.
● No confien en frameworks ciegamente.
● No implementen sus propias funciones de criptografía (A menos que sean
expertos en crypto).
● Inviertan en entrenamiento sobre programación segura.
● Almacenen sus bitácoras de forma segura.
● Verifiquen su sistema de autenticación y autorización.
● Realicen ejercicios de auditoría de código.
● Consideren a la seguridad en su ciclo de desarrollo de software.
● Consideren implementar un programa de recompensa por reportar bugs.
● No usen una sola herramienta.