Developers - no es chiste: Así hacemos seguridad en Microsoft
“When we started work on Microsoft .NET more than two years ago, we set a new direction for the company -- and articulated a new way to think about our software. Rather than developing standalone applications and Web sites, today we're moving towards smart clients with rich user interfaces interacting with Web services.
…
However, even more important than any of these new capabilities is the fact that it is designed from the ground up to deliver Trustworthy Computing. What I mean by this is that customers will always be able to rely on these systems to be available and to secure their information. Trustworthy Computing is computing that is as available, reliable and secure as electricity, water services and telephony. “
Así anunciaba Bill Gates en el año 2002 el comienzo de la iniciativa conocida como Trustworthy Computing, enfocada en desarrollar una serie de procesos y prácticas enfocados en cuatro pilares específicos: Seguridad, Privacidad, Confiabilidad e Integridad en los Negocios en los diferentes productos y servicios ofrecidos por Microsoft.
En este artículo describiré brevemente uno de los resultados de esta iniciativa: Microsoft Security Development Lifecycle. Al final del mismo, les haré una invitación a que me compartan qué tipos de consideraciones de seguridad realizan en sus equipos.
Microsoft Security Development Lifecycle
Se trata de un proceso de QA, explicitando actividades obligatorias que deben ser aplicadas en las diferentes etapas del ciclo de desarrollo: Entrenamiento, Requerimientos, Diseño, Implementación, Verificación, Liberación, Respuesta.
0 - Entrenamiento
El primer punto es crucial, considerar el entrenamiento en seguridad una etapa obligatoria propia del ciclo de desarrollo. El entrenamiento no es solo requerido para el desarrollador, sino también para los roles de tester o program manager (para conocer más del modelo de organización de equipos en Microsoft, ver MSF).
Algunos conceptos básicos incluidos en el entrenamiento requerido:
- Diseño seguro: Reducción de superficie de ataque, defensas de profuncidad, principio del menor privilegio (otorgar el menor privilegio que necesita el usuario y no más), valor por defecto seguros.
- Modelo de amenazas (threat model): Diseño, codificación y testing para un modelo de amenazas.
- Codificación segura: Buffer overruns, errores de aritmética de enteros, Cross-site scripting, SQL Injection, Criptografía débil, Errores de código manejado (estoy escribiendo otro post sobre este item en particular).
- Testeando la seguridad: Testeo de seguridad vs. funcional, manejo de riesgos, metodologías y automatización de tests.
- Privacidad: Tipos de datos privados, mejores prácticas en diseño de privacidad, análisis de riesgo, mejores prácticas de desarrollo y testing de Privacidad.
Dos libros para conocer más sobre prácticas de desarrollo seguro:
1 – Requerimientos
Durante el inicio del proyecto no sólo debe evaluarse las condiciones generales de seguridad y privacidad a ser consideradas durante todo el proyecto, sino hacerse un análisis de costos para asegurar dichas características. Cuanto más temprano identifiquemos defectos de seguridad en nuestro proyecto, menor será el costo de resolverlos, por eso es muy importante el planeamiento de los mismos:
Para ello debe realizarse un análisis de riesgos el cual incluya:
- Qué porciones del proyecto requerirán un Modelo de Amenazas antes de ser liberado.
- Qué porciones del proyecto requerirán revisiones de diseño de seguridad antes de ser liberado.
- Que porciones del proyecto requerirán testeo de penetración el cual es realizado por un grupo de gente externa al equipo del proyecto.
- Cualquier test adicional o análisis de requerimiento que el Security Advisor considere necesario para mitigar riesgos de seguridad.
A su vez, se realiza un análisis de privacidad, que identifique el grado de sensibilidad de los datos a ser procesados por el software. A partir de este tipo de análisis, se definen las barreras de seguridad que debe cumplir el software.
2 – Diseño
Desde una perspectiva de seguridad, los elementos más importantes durante la fase de diseño son la definición de la arquitectura y guías de diseño de seguridad: La definición de capas, el uso o no de lenguajes fuertemente tipados, la definición de los menores privilegios requeridos, la minimización de la superficie de ataques, deben ser consideradas y aplicadas al software de acuerdo a los requerimientos definidos.
A su vez, el proceso definido establece algunas prácticas requeridas:
- Realizar revisiones de diseño de seguridad, llevadas adelantes por el Security Advisor.
- Al utilizar código manejado, deben utilizarse assemblies fuertemente tipados, requiriendo el permiso mínimo.
- Seguir las mejores prácticas definidas por User Account Control (UAC) . El tener esto en cuenta, permite desarrollar aplicaciones que requieran un usuario con los mínimos privilegios, reduciendo así las superficies de ataque.
- Evitar la modificación de las configuraciones de Firewall durante la ejecución de la aplicación.
- Se define un Estándard de Criptografía Microsoft, identificando algorítmos de alto nivel para protección de la información.
- La instalación por defecto debe realizar configuraciones seguras.
- Si se trata de una nueva versión de producto, deben revisarse las causas raiz de defectos de seguridad encontrados en el pasado.
- Debe deprecarse toda funcionalidad desactualizada.
- Todo código nuevo, debe implementarse utilizando código manejado de ser posible.
3 – Implementación
La definición de un Modelo de Amenazas cobra especial atención durante la fase de implementación. Los desarrolladores prestan especial atención a la correctitud del código, mitigando las amenazas de mayor prioridad, permitiendo a los testers asegurar que cada amenaza es realmente bloqueada y mitigada.
Las practicas recomendadas durante esta fase incluyen:
Creación de documentación para el usuario, informando sobre consideraciones de seguridad de la aplicación.
Establecer y Seguir las Mejores Practicas de Desarrollo:
- Utilizar siempre la última version del compilador.
- Utilizar herramientas de análisis estático de código.
- Evitar utilizar APIs deprecadas o prohibidas.
- Validar SIEMPRE los parámetros de entrada, y encodear debidamente los parámetros de salida (especialmente para servicios online).
- NUNCA realizar queries SQL ad-hoc, evitando SQL Injection. Utilizar Stored Procedures, y evitar la entrega de permisos excesivos en los usuarios de conexión a la DB.
- Al utilizar código manejado, correr herramientas de análisis estático como FxCop.
- En código no manejado, debe habilitarse Address Space Layout Randomization. Esto fué introducido en Windows Vista, y asegura que las direcciones de memoria utilizadas por una aplicación siempre sean diferentes en cada corrida.
- Establecer reglas que debe cumplir el código antes de hacer check in al repositorio central.
- Para aplicaciones que utilicen Javascript, evitar el uso de la función eval() .
- Verificar que los mensajes de error sean seguros, sin exponer información comprometida de la aplicación.
- Si la aplicación hace accesos a disco, construir una lista de archivos conocidos que ésta puede modificar.
- Ante una URL inválida, devolver un error 400 al usuario, logueando el error real.
- Y la lista continua y continua…
4 – Verificación
Se trata del punto donde la funcionalidad es completa y entra en testeo beta de usuario. Se realiza beta testing, haciendo un gran esfuerzo por violar la seguridad del sistema, y realizando revisiones de seguridad periódicas de código.
El testeo de seguridad de comenzar muy temprano en la etapa de verificación. También se vuelve clave la definición de la superficie de ataque, dado que permitirá priorizar los defectos encontrados, entendiendo cuales de ellos deben ser corregidos inmediatamente.
5 – Liberación
Durante la liberación, el software debe someterse a una Revisión Final de Seguridad: Desde el punto de vista de la seguridad, está el producto listo para los clientes?
La Revisión Final de Seguridad no es un ejercicio donde simplemente se determina si pasa o no pasa; tampoco el objetivo es encontrar el resto de las vulnerabilidades del software, esto podría no lograrse nunca. En lugar de esto, la Revisión Final permite darle al equipo de producto y a la organización una visión general de la seguridad del software, y la probabilidad de que ocurran ataques una vez que es liberado a los clientes. Si se encontraran vulnerabilidades, la respuesta correcta no es simplemente corregirlas, sino revisar las faces anteriores y tomar otras acciones que permitan corregir las causas de raiz (por ejemplo mejorando el entrenamiento, perfeccionando las herramientas).
6 – Respuesta o Soporte
A pesar de aplicar el proceso durante el desarrollo, las prácticas de desarrollo actuales aún no permiten entregar software que esté completamente libre de vulnerabilidades – y existen razones para creer que esto no va a ocurrir nunca. Por ello, los grupos de producto deben prepararse para responder a nuevas vulnerabilidades encontradas aún cuando el software ya fué liberado.
Parte del proceso de respuesta involucra la generación de reportes de vulnerabilidades, y liberar actualizaciones cuando corresponda. El otro componente del proceso de respuesta, es llevar adelante post-mortems de vulnerabilidades reportadas, permitiendo tomar las acciones necesarias.El objetivo es lograr aprender de los errores y utilizar los reportes de vulnerabilidades para encontrar nuevas vulnerabildiades que aún no hayan sido encontradas, antes de poner a los clientes en riesgo.
Implementando SDL en Microsoft y otras variantes
Microsoft implementa SDL desde el año 2002. Productos como Windows Server 2003, Windows Vista, Windows 7, SQL Server 2005 en adelante son el resultado de la aplicación de las prácticas de ingeniería que surgieron a partir de la iniciativa de Trustworthy Computing.
Los equipos de ingeniería deben aplicar estos procesos de forma obligatoria, siendo la seguridad un rol central en el equipo. Visual Studio Team System, incluye una plantilla de proceso SDL. Herramientas como SDL Threat Modeling Tool facilitan la definición y administración de los Modelo de Amenazas.
Procesos Ágiles: Existen también definiciones adyacentes al proceso de SDL, enfocada a proveer prácticas y soluciones para equipos con metodologías ágiles, también descriptas dentro del documento: Microsoft Security Development Lifecycle
El post hasta aquí ha sido una muy breve descripción a manera de introducción al proceso seguido en equipos de Microsoft para asegurar la calidad en sus productos. Algunas de estas prácticas te habrán parecido comunes, y otras tal vez nuevas. Te invito me compartas qué significa para vos la seguridad, y cómo es considerada dentro de tu equipo de desarrollo.
Saludos!