Vea cómo integrar fácilmente el análisis estático, las pruebas unitarias y otros métodos de prueba de software C y C++ en su canalización de CI/CD. Regístrese para la demostración >>

Cómo hacer que las pruebas de seguridad de API sean una parte automatizada del proceso de CI

Por Nathan Jakubiak

21 de octubre de 2021

7  min leer

Dado que las pruebas de penetración son costosas y pueden tardar mucho en ejecutarse, debemos realizar las pruebas de seguridad de API de una manera que sea escalable y sostenible.

Hablar de la seguridad de las API y de por qué deberíamos preocuparnos es un poco como hablar de comer nuestras verduras. Todos sabemos que comer nuestras verduras es bueno para nuestra salud, pero ¿cuántos de nosotros lo hacemos realmente? La seguridad de las aplicaciones es un poco así. Si bien es esencial para la salud de nuestras aplicaciones y nuestros negocios, esforzarse por lograrlo no es tan interesante como crear nuevas funciones interesantes para las aplicaciones. Pero solo tenemos que mirar los titulares de las noticias recientes para comprender lo importante que es.

Tradicionalmente, la validación de una aplicación o API por seguridad se ha realizado al final del proceso de desarrollo. Sin embargo, esto es intrínsecamente problemático. Por lo general, es demasiado tarde en el proceso para que se solucionen los errores descubiertos: puede que esté demasiado cerca de la fecha de lanzamiento para solucionar los problemas, o el equipo puede haber pasado a otros proyectos, o la arquitectura de la aplicación puede ser inherentemente insegura.

Además, los servicios y las aplicaciones de hoy en día se publican con más frecuencia que nunca, a menudo hasta varias veces al día. Esta cadencia de liberación rápida hace que el enfoque tradicional sea insostenible. En este blog revisaré un paso a paso Lista de verificación de seguridad de la API para hacer que las pruebas de seguridad de la API sean una parte automatizada del proceso de CI.

Entrar en integración continua

Para resolver este problema, recurriremos a una solución que la industria ha estado utilizando para abordar los problemas de calidad del software con ciclos de lanzamiento acelerados: la integración continua. La integración continua produce compilaciones cada vez que se registra un nuevo código y valida el nuevo código mediante la ejecución de análisis estáticos y pruebas unitarias para cada compilación. Si los equipos son sofisticados, incluso podrían estar creando y ejecutando pruebas funcionales automatizadas mediante CI (quizás no para cada compilación, ya que las pruebas funcionales suelen tardar mucho tiempo en ejecutarse, pero al menos a intervalos específicos, como una vez al día).

Podemos aplicar esta misma solución a las pruebas de seguridad automatizadas para nuestras API al incorporar las pruebas de penetración en nuestros flujos de trabajo de CI. Esto asegurará que probaremos las vulnerabilidades de seguridad antes y nos dará pruebas de regresión de seguridad que pueden detectar nuevos problemas tan pronto como se presenten. Pero tendremos que ser inteligentes al respecto, ya que las pruebas de penetración son caras y pueden tardar mucho en ejecutarse. Debemos hacerlo de una manera escalable y sostenible.

Comience con pruebas funcionales

Supongo que nuestros equipos ya están escribiendo y ejecutando pruebas funcionales automatizadas para nuestras API. (Si no estamos haciendo esto, debemos comenzar aquí y no estamos listos para considerar la automatización de nuestras pruebas de seguridad). Si estamos ejecutando pruebas funcionales automatizadas para nuestras API, entonces, como parte de nuestros procesos normales de desarrollo y control de calidad, podemos identificar un subconjunto de esas pruebas funcionales para usar como pruebas de seguridad. Prepararemos y ejecutaremos este subconjunto como pruebas de seguridad.

Permítanme describir cómo funciona esto usando Prueba SOA de Parasoft y su incorporado pruebas de penetración soporte, que se incluye en el 2021.2 liberación.

¡Vea Parasoft SOAtest en acción!

Para empezar, supongamos que tenemos un escenario SOAtest con 1 prueba de configuración que limpia la base de datos y 3 pruebas que realizan 3 llamadas API diferentes. Queremos realizar pruebas de penetración para cada una de las 3 API que se llaman en el escenario:

Captura de pantalla del escenario SOAtest de Parasoft con 3 llamadas API diferentes.

Primero prepararemos el escenario para la seguridad agregando una herramienta de prueba de penetración a cada una de las pruebas en el escenario:

Captura de pantalla de Parasoft SOAtest preparando el escenario de seguridad agregando una herramienta de prueba de penetración.

Luego, ejecutaremos este escenario usando SOAtest. A medida que se ejecuta cada prueba, SOAtest realizará la llamada a la API definida en la prueba y capturará el tráfico de solicitud y respuesta. La herramienta de prueba de penetración en cada prueba pasará los datos de tráfico a una instancia integrada de la herramienta de prueba de penetración OWASP ZAP, que realizará pruebas de penetración en la API en función de los parámetros de la API que observa en los datos de tráfico, utilizando su propia heurística.

La herramienta de prueba de penetración informará los errores encontrados asociados con la prueba que accedió a la API. Aquí hay un informe SOAtest de muestra con todos los errores organizados por CWE y por gravedad:

Tabla que muestra los problemas de seguridad de la API y el nivel de riesgo frente al nivel de confianza por CWE.Los resultados de SOAtest pueden informarse en DTP, el panel de análisis e informes de Parasoft, para obtener capacidades de informes adicionales. Aquí hay una representación de cómo funciona esto:

Gráfico de flujo que muestra cómo se informan los resultados de SOAtest en DTP, el panel de análisis e informes de Parasoft.

La reutilización de las pruebas funcionales para su uso como pruebas de seguridad ofrece los siguientes beneficios:

  1. Como ya estamos escribiendo pruebas funcionales, podemos reutilizar el trabajo que ya se ha realizado, ahorrando tiempo y esfuerzo.
  2. Para ejecutar ciertas API, es posible que tengamos que realizar alguna configuración, como preparar la base de datos o llamar a otras API. Si comenzamos con pruebas funcionales que ya funcionan, esta configuración ya está hecha.
  3. Por lo general, una herramienta de prueba de penetración informará que una determinada llamada API tiene una vulnerabilidad, pero no brinda ningún contexto sobre el caso de uso y / o requisito al que está conectada. Dado que utilizamos SOAtest para ejecutar los casos de prueba, las vulnerabilidades de seguridad se informan en el contexto de un caso de uso. Cuando los escenarios se han asociado con los requisitos, ahora podemos obtener un contexto comercial adicional sobre el impacto de los errores de seguridad en la aplicación.
  4. Tenemos un escenario de prueba que podemos utilizar para reproducir fácilmente el error o para validar que se ha solucionado.

Preparación de pruebas funcionales para su uso como pruebas de seguridad

Hay algunas cosas a tener en cuenta al reutilizar las pruebas funcionales para su uso como pruebas de penetración:

  1. Debemos mantener nuestros escenarios de prueba funcionales separados de nuestros escenarios de prueba de seguridad y ejecutarlos desde trabajos de prueba separados. La razón principal de esto es que agregar pruebas de penetración a las pruebas funcionales existentes probablemente servirá para desestabilizar las pruebas funcionales. Necesitamos seleccionar qué escenarios de prueba funcional deben convertirse en pruebas de seguridad automatizadas y luego hacer copias de las pruebas funcionales que se mantendrán como pruebas de seguridad independientes.
  2. Debemos ser selectivos en las pruebas que elegimos, ya que las pruebas de penetración son caras; necesitamos maximizar la superficie de ataque de la API que está cubierta mientras minimizamos el número de pruebas. Debemos considerar lo siguiente:
    • Las herramientas de prueba de penetración analizan el tráfico de solicitudes / respuestas para comprender qué parámetros de la solicitud están disponibles para ser probados. Necesitamos seleccionar pruebas funcionales que ejerciten todos los parámetros en cada API, para asegurarnos de que cada entrada a la API sea analizada.
    • Dentro de cada escenario, debemos decidir qué llamadas API deben probarse. Se puede hacer referencia a la misma API desde múltiples escenarios, y no queremos duplicar las pruebas de penetración en una API que se está probando en un escenario diferente. La herramienta de prueba de penetración solo debe agregarse a las pruebas apropiadas para que las API sean probadas de penetración.
    • El número de escenarios debe ser manejable para que la ejecución de la prueba de seguridad sea lo suficientemente corta como para ejecutarse al menos una vez al día.
  1. Nuestros escenarios de prueba funcional pueden tener secciones de configuración o desmontaje para inicialización o limpieza. Por lo general, no es necesario realizar una prueba de penetración.
  2. Si la prueba funcional tiene alguna parametrización, deberíamos eliminarla. Las herramientas de prueba de penetración no necesitan múltiples conjuntos de valores para los mismos parámetros para saber qué probar y el envío de diferentes conjuntos de valores podría llevar a que las ejecuciones de prueba sean más largas debido a pruebas duplicadas.
  3. Las pruebas funcionales de API generalmente tendrán afirmaciones que validan la respuesta del servicio. Cuando se utilizan como pruebas de seguridad, estas afirmaciones pueden fallar pero serán ruidosas al revisar los resultados, ya que en este contexto solo nos preocupamos por las vulnerabilidades de seguridad que se encontraron. Deberíamos eliminar todas las afirmaciones. En mi ejemplo anterior, esto significaría eliminar JSON Assertor de la Prueba 3.
  4. Algunas llamadas a la API agregan datos a la base de datos. Cuando se usa una herramienta de prueba de penetración contra dichas API, la base de datos puede llenarse de información debido a la cantidad de ataques que la herramienta de prueba de penetración dirige a la API. En algunos casos, esto puede provocar efectos secundarios inesperados. En uno de nuestros equipos de desarrollo, descubrimos un problema de rendimiento en la aplicación cuando una API en particular agregó muchos datos debido a los ataques de prueba de penetración. El rendimiento de la aplicación se volvió tan malo que impidió que la prueba de seguridad automatizada finalizara en un período de tiempo razonable. Tuvimos que excluir las pruebas de seguridad para esa API de nuestra ejecución automatizada hasta que resolviéramos el problema.

Mantener un entorno de prueba estable

Necesitamos considerar si ejecutar nuestras pruebas funcionales y de seguridad dentro del mismo entorno de prueba o en uno diferente. Restablecer el entorno entre las ejecuciones de prueba funcional y de seguridad, o usar un entorno separado, promueve una mejor estabilidad de la prueba, pero generalmente no es necesario. A menudo podemos reutilizar el mismo entorno, pero cuando lo hacemos, debemos ejecutar las pruebas funcionales primero y las pruebas de seguridad al final, ya que las pruebas de seguridad pueden desestabilizar el entorno para las pruebas funcionales. Cuando usamos diferentes entornos, debemos asegurarnos de configurar los escenarios de prueba funcionales originales con variables para que sea fácil apuntar las pruebas a diferentes puntos finales para diferentes entornos. SOAtest admite esto mediante el uso de variables de entorno.

Nuestras API también pueden depender de otras API fuera de nuestro control. Podemos considerar el uso virtualización de servicios para aislar nuestro entorno así que no dependemos de esos sistemas externos. Esto ayudará a estabilizar nuestras pruebas y, al mismo tiempo, evitará consecuencias no deseadas en los sistemas externos debido a nuestros esfuerzos de pruebas de penetración.

Satisfaga todas sus necesidades de pruebas de API, desde simples hasta complejas, todo sin secuencias de comandos.

Conclusión

Podemos garantizar una mejor calidad en nuestras API trasladando las pruebas de seguridad al desarrollo y control de calidad como parte de un proceso automatizado. Podemos aprovechar nuestras pruebas funcionales de API existentes para crear pruebas de seguridad automatizadas, lo que nos permitirá descubrir y corregir errores de seguridad en una etapa más temprana del proceso. Y con suerte, esto nos ayudará a no convertirnos en uno de los próximos grandes titulares en las noticias.

Por Nathan Jakubiak

Nathan es Director de Desarrollo de Parasoft. Él y sus equipos desarrollan capacidades de productos en las áreas de pruebas de UI (Selenic), pruebas de API (SOAtest), virtualización de servicios (Virtualize) y pruebas unitarias (Jtest). Ha estado con Parasoft desde 2000.

Reciba las últimas noticias y recursos sobre pruebas de software en su bandeja de entrada.