Una de las frases más famosas de Seymour Cray (creador de los superordenadores CRAY) es: «El problema con los programadores es que nunca puedes saber lo que un programador está haciendo hasta que es demasiado tarde». Un error no identificado a tiempo en el código fuente de un aplicativo específico puede causar incidentes tan críticos como los sucedidos con la omisión de los dos primeros dígitos de los años en los formatos de fechas que generó la crisis del problema del año 2000 (Y2K), la desviación de la sonda de la NASA Mariner 1 que iba a Venus causada por un error de código en FORTRAN, el error en la gestión de la memoria en OpenSSL que causo el famoso «heartbleed» o la muerte de 28 soldados estadounidenses en Arabia Saudí debido a un error de código en el sistema de misiles tierra-aire MIM-104 Patriot, por solo nombrar algunos.

En el año 2002, el National Institute of Standards and Technology (NIST) informaba que los errores o fallos de software son tan frecuentes y tan perjudiciales que le costaban a la economía estadounidense unos 59.500 millones de dólares anuales, o alrededor del 0,6 por ciento del producto interior bruto. En el estudio también se llegó a la conclusión de que, aunque no se pueden eliminar todos los errores, más de un tercio de esos costos, o sea unos 22.200 millones de dólares, podrían eliminarse mediante una infraestructura de pruebas mejorada que permita identificar y eliminar antes y con mayor eficacia los defectos de los programas informáticos.

En esta séptima parte de la serie «Controles técnicos de PCI DSS» se discutirán de forma general los controles relacionados con la revisión manual o automática del código fuente, conforme se indica en el estándar PCI DSS.

¿En qué consiste el análisis de código fuente (White Box)?

Un error de software (también conocido como bug) es una falla en un programa (software) que produce un resultado o un comportamiento incorrecto o inesperado del mismo, interfiriendo con su funcionalidad y afectando no solamente su operación sino también su seguridad.

Con el fin de identificar y corregir potenciales errores (intencionales o no) por parte de los programadores durante el proceso de desarrollo de software que puedan impactar en la confidencialidad, la integridad y/o la confidencialidad de los datos procesados, almacenados o transmitidos por un programa en particular, es necesario establecer una serie de acciones preventivas y correctivas dentro del ciclo de vida del desarrollo de software (Software Development Life Cycle – SDLC), entre las que se encuentran la formación en desarrollo seguro para los programadores, la ejecución de escaneos de vulnerabilidades y pruebas de penetración y la revisión de código fuente, entre otras. Estas acciones entran a complementar el SDLC tradicional para añadir una capa adicional de seguridad, lo que se conoce como Secure SDLC o S-SDLC.

Figura 1. SDLC vs. SSDLC (fuente: SoftServe)

De estas acciones, probablemente la revisión de código fuente (code review) es una de las más técnicas más efectivas para la detección de fallos en el software, ya que se puede incorporar en las fases iniciales del SDLC guiando al desarrollador a la raíz del problema y permitiendo una detección temprana de los errores de programación directamente en el código fuente de la aplicación, lo cual resulta en minimización de costes y esfuerzos.

Este tipo de revisiones se puede desarrollar mediante dos enfoques:

  • Revisión de código fuente manual (manual source code analysis), en donde un desarrollador o un equipo de desarrollo especializado (diferentes a la persona o al equipo que ha escrito el código) se encargan de realizar una revisión manual del código fuente, basándose en las mejores prácticas de la industria y en guías de desarrollo seguro dependiendo del lenguaje de programación empleado. Este tipo de revisiones otorgan una validación más detallada del contexto del código (cosa que una aplicación no puede realizar), pero a su vez requiere de tiempo y esfuerzo en función de la cantidad de líneas de código analizadas y su complejidad y puede no detectar la totalidad de los errores de programación.
  • Revisión automática de código (automatic code analysis), que emplea el uso de herramientas de software para la validación del código fuente en busca de errores con base en una serie de reglas y firmas preestablecidas. Este tipo de herramientas reciben el nombre de Static Application Security Testing (SAST).

El resultado de la ejecución de cualquiera de estas dos herramientas es un reporte que debe ser entregado al desarrollador para que pueda corregir los errores detectados (no existe una corrección automática). Como se puede ver, es importante que se establezcan políticas para la ejecución regular de estos ejercicios de revisión de código en cada una de las fases del proceso de desarrollo. De lo contrario, los errores no identificados pueden heredarse a fases de desarrollo posteriores.

¿En qué consisten las revisiones de aplicación (Black Box)?

De forma complementaria, en fases más avanzadas del desarrollo se puede hacer uso de otro tipo de herramientas automatizadas denominadas Dynamic Application Security Testing (DAST), que se encargan de realizar un análisis del comportamiento de una aplicación durante su ejecución (run-time). La diferencia fundamental con SAST es que las revisiones basadas en DAST no requieren del código fuente de la aplicación a ser analizada.

Figura 2. SAST vs. DAST (fuente: Synopsys)

Recientemente, otros dos enfoques están siendo empleados para la detección y contención de errores de programación, más allá de la revisión de código estático:

  • Interactive Application Security Testing (IAST), que, mediante la instalación de un agente dentro de la aplicación, permite la realización de un análisis completo del comportamiento de librerías, frameworks, flujos de datos, conexiones con servicios de backend y otros componentes, con resultados más precisos que los provistos por SAST y DAST.
  • Run-time Application Security Protection (RASP), que, aparte de realizar una revisión para la detección de errores, permite controlar la ejecución de la aplicación para contener y mitigar el potencial impacto de dichos errores a la vez que alerta al personal de seguridad de los fallos identificados.

Este conjunto de aplicaciones para la identificación de errores de programación (SAST, DAST, IAST y RASP) reciben el nombre de «herramientas de pruebas de seguridad de aplicaciones» o application security testing tools.

Figura 3. Diferencias entre SAST, IAST, DAST y RASP (fuente: Synopsys)

Revisión de código y PCI DSS

Con el fin de minimizar los posibles errores de programación en los aplicativos que se despliegan en el entorno de producción y evitar la exposición del software a ataques que puedan aprovechar estos fallos, el estándar PCI DSS requiere que se ejecute una revisión de código fuente antes de publicarlo en producción o entregarlo a los clientes, conforme se especifica en el requerimiento 6.3.2 de PCI DSS v3.2.1:

6.3.2 Review custom code prior to release to production or customers in order to identify any potential coding vulnerability (using either manual or automated processes) to include at least the following:

  • Code changes are reviewed by individuals other than the originating code author, and by individuals knowledgeable about code-review techniques and secure coding practices.
  • Code reviews ensure code is developed according to secure coding guidelines
  • Appropriate corrections are implemented prior to release.
  • Code-review results are reviewed and approved by management prior to release.

Note: This requirement for code reviews applies to all custom code (both internal and public-facing), as part of the system development life cycle.
Code reviews can be conducted by knowledgeable internal personnel or third parties. Public-facing web applications are also subject to additional controls, to address ongoing threats and vulnerabilities after implementation, as defined at PCI DSS Requirement 6.6.

En este sentido, desde la perspectiva de PCI DSS, el uso de una revisión de código fuente manual o de una revisión automática de código (SAST) son válidas para cumplir con el requerimiento. Dicha revisión debe ser realizada por otra persona o equipo diferente al que ha escrito el código, debe seguir las guías de desarrollo seguro (por ejemplo OWASP Code Review Guide), se deben aplicar las correcciones necesarias antes de su publicación y los resultados de este análisis deben ser revisados y aprobados por la Dirección.

Otro elemento a tener en cuenta es que todo el código desarrollado internamente (ya sea para aplicaciones internas o publicadas en internet) debe ser revisado empleando estas técnicas. Esto incluye no solamente las aplicaciones propiamente dichas sino también cualquier otra dependencia empleada (por ejemplo, librerías).

Por otro lado, el uso de herramientas tipo DAST, IAST y/o RASP no son obligatorias por PCI DSS, pero pueden ser empleadas como controles compensatorios en el caso de que se identifiquen restricciones técnicas o administrativas que impidan el uso de revisiones manuales o automáticas de código fuente.

Herramientas para la revisión de código fuente y seguridad en aplicaciones

En términos de herramientas que pueden ser usadas para cumplir con el requerimiento 6.3.2 de PCI DSS v3.2.1, a continuación se enumeran algunos sitios web que pueden ser usados como referencia:

No olvides dejarnos tus preguntas en los comentarios del artículo y el foro.


David Acosta

Asesor de Seguridad Calificado (QSA) para PCI DSS, P2PE, PIN, 3DS, TSP y PIN.
CISSP Instructor, CISA, CISM, CRISC, CHFI Trainer, CEH, OPST, BS25999 LA.