
Introducción
Normalmente, las empresas de software ven la seguridad como una idea de último momento, que se suele añadir cuando el producto está completamente operativo. Este enfoque podía ser discutible en el pasado. Hoy en día, se considera una mala decisión, ya que podría generar vulnerabilidades inesperadas en el código fuente liberado.

En DevOps nos proporciona un nuevo paradigma en nuestros equipos, un nuevo rol con un fondo de desarrollador centrado en la integración continua, combinando y automatizando todos los componentes de desarrollo varias veces al día. La automatización, el despliegue y la escalabilidad son temas cotidianos en el DevOps concepto. Si combinamos este rol y la seguridad, podemos encontrar tareas relacionadas con DevSecOps que se centran en Ciclo de vida del desarrollo de software (SDLC). De este modo, podemos tomar las buenas prácticas de DevOps y aplicarlos a las comprobaciones de seguridad en conjunto como un proceso continuo, lo que nos proporciona el mismo nivel de automatización de la aplicación para todos los atributos de seguridad, funcionales y no funcionales. Todas estas variables promueven un sistema de software más seguro y robusto.
Paso 1: Crear una aplicación Heroku
En primer lugar, tenemos que crear un Heroku aplicación. Para ello, recomendamos seguir las instrucciones del sitio web oficial. Puedes optar por otros servicios similares -como DigitalOcean o AWS-, pero ten en cuenta que el siguiente flujo de trabajo de GitHub debe modificarse.
Paso 2: Crear un repositorio GitHub con nuestra aplicación vulnerable
Necesitamos crear un repositorio GitHub y subir nuestra app vulnerable allí. Asegúrate de que el proceso de despliegue manual con Heroku (o el servicio que hayas elegido) funciona en tu local. Para este ejemplo, hemos utilizado este repositorio .
Paso 3: Crear un flujo de trabajo de Acciones de GitHub
¡Este es el objetivo de este blog! Tenemos que crear nuestro flujo de trabajo GitHub que se ejecutará siguiendo algunas reglas definidas por nosotros.
Para este blog, hemos decidido ejecutar nuestro flujo de trabajo cuando un usuario ejecute el comando pulse sobre el rama maestra.
Por lo tanto, vaya a su repositorio y cree este árbol de directorios en la raíz del mismo: .github/workflow . A continuación, crear un archivo .yml dentro, en nuestro caso hemos creado un ci.yml archivo.

Como dijimos antes, primero tenemos que definir el nombre de nuestro flujo de trabajo y el evento desencadenante.
nombre: CIen: pulse: ramas: - maestro
Como dijimos antes, primero tenemos que definir el nombre de nuestro flujo de trabajo y el evento desencadenante.
trabajos: construir: se ejecuta: ubuntu-latestescanear: necesidades: [construir] sigue corriendo: ubuntu-latestsubir: necesidades: [scan] sigue corriendo: ubuntu-latest
Hemos definido 3 puestos de trabajo: construya, escanear y subir, y todos ellos se ejecutan sobre una imagen ubuntu-latest.
Acciones de GitHub ejecutar todos los trabajos al mismo tiempo, pero para este ejemplo necesitamos ejecutarlos secuencialmente. Para ello, utilizamos la propiedad necesita. Por lo tanto, el escanear tiene la propiedad necesidades: [construir] y el cargar tiene la propiedad necesidad: [escanear]. Así nos aseguramos de que se ejecutan en orden secuencial.
Etapa 3.1: Definición de la Construya empleo
construya: funciona en: ubuntu-latestpasos: - utiliza: actions/checkout@v1- nombre: Utilizar Python usos: actions/setup-python@v2 con: python-version: '3.x' arquitectura: 'x64'- nombre: Instalar dependencias correr: | python -m install - upgrade pip pip install -r requisitos.txt- nombre: Ejecutar Bandit (analizador de código Python) correr: bandit -r . -f xml -o flaskapp_faraday_bandit.xml || true- nombre: Cargar informe de bandido usos: actions/upload-artifact@v2 con: nombre: bandido-informe camino: flaskapp_faraday_bandit.xml- nombre: Añadir origen remoto correr: | git remote add heroku https://heroku:${{ secrets.HEROKU_API_KEY }}@git.heroku.com/${{ secrets.HEROKU_APP_NAME }}.git- nombre: Despliegue en Heroku correr: git push heroku HEAD:master -f
La primera acción a ejecutar es actions/checkout@v1. Esto descargará nuestro repositorio en el espacio de trabajo asignado por GitHub.
El siguiente paso declara un entorno Python 3 e instala la dependencia del repositorio utilizando el archivo requisitos.txt. Este archivo tiene Bandit como dependencia por lo que podemos usarlo ahora.
A continuación, ejecutamos Bandido. Esto creará un informe en xml con el nombre flaskapp_faraday_bandit.xml. Para Insights y Blog es importante prestar atención al sufijo Bandit.xml, porque se utilizará para reconocer el informe del plugin cuando lo subamos a nuestro Insights y Blog instancia.
Una vez que Bandit haya terminado, tenemos que subir el informe generado a GitHub utilizando actions/upload-artifact@v2. Esta acción combinada con acciones/descargar-artifact@master son los mecanismos proporcionados por GitHub Actions para compartir resultados entre trabajos.
Las dos últimas acciones son las Heroku despliegue. Una nota importante aquí es que hemos utilizado las variables secretos.HEROKU_API_KEY y secretos.HEROKU_APP_NAME. Estas variables pueden definirse en el Secretos sección sobre el Ajustes de nuestro repositorio GitHub:

Al declarar estas variables secretas, podemos evitar introducir información sensible directamente en nuestro archivo de flujo de trabajo.
Paso 3.2: Definir el Escanear empleo
escanear: necesidades: [construir] funciona en: ubuntu-latestcontenedor: imagen: owasp/zap2docker-stable opciones: - usuario root -v ${{ github.workspace }}:/zap/wrk/:rwpasos: - nombre: Ejecutar Zap Baseline Scan correr: zap-baseline.py ${{ secrets.ZAP_SCAN_URL }} -x zap-report.xml || echo 0- nombre: Cargar artefacto de informe Zap usos: actions/upload-artifact@v2 con: nombre: zap-informe camino: zap-informe.xml
Este trabajo ejecutará un escaneo simple sobre nuestra aplicación vulnerable recientemente desplegada.
Como puede ver, hemos utilizado una versión dockerizada de Zap de OWASP. Por esta razón, necesitamos elegir la imagen docker y declarar algunas opciones.
A continuación, ejecutamos la exploración y guardamos el informe con el nombre zap-informe.xml.
Por último, cargamos el informe como hicimos con el informe Bandit en la tarea de creación.
Paso 3.3: Definir el Cargar empleo
cargar: necesita: [scan] funciona en: ubuntu-latestcontenedor: imagen: python:3.9.1 opciones: - usuario root -v ${{ github.workspace }}:/informes:rwpasos:- nombre: Obtener la fecha actual id: fecha correr: echo "::set-output name=fecha::$(fecha +'%Y-%m-%d')" - nombre: Descargar el informe Zap usos: acciones/descargar-artifact@master con: nombre: zap-informe camino: zap-informe- nombre: Descargar el artefacto Bandit Report usos: acciones/descargar-artifact@master con: nombre: bandido-informe camino: bandido-informe- nombre: Cargar informes en Faraday correr: | pip install faraday-cli faraday-cli auth -f ${{secretos.FARADAY_HOST }} -u ${{ secretos.FARADAY_USERNAME }} -p ${ secrets.FARADAY_PASSWORD }} faraday-cli create_ws ${{ github.event.repository.name }}-${ steps.date.outputs.date }}-${ github.run_number }} faraday-cli process_report -w ${{ github.event.repository.name }}-${ steps.date.outputs.date }}-${{ github.run_number }} /reports/bandit-report/flaskapp_faraday_bandit.xml faraday-cli process_report -w ${{ github.event.repository.name }}-${{ steps.date.outputs.date }}-${{ github.run_number }} /reports/zap-report/zap_report.xml
En este trabajo, vamos a subir los dos informes generados a nuestro Insights y Blog instancia.
Para ello, necesitamos utilizar la biblioteca faraday-cli que pueden instalarse fácilmente con pip mando.
Así, definimos el trabajo Upload para que funcione dentro de una imagen docker con Python 3 para permitirnos instalar faraday-cli fácilmente después.
A continuación generamos una variable guardando la fecha actual con el formato AAAA-mm-dd. Esta variable se utilizará para el nombre del espacio de trabajo en nuestro Insights y Blog instancia.
Ahora, tenemos que descargar los dos informes generados en los trabajos ejecutados anteriormente utilizando el comando acciones/descargar-artifact@master acción.
Por último, tenemos que instalar faraday-cli y luego realizar una autenticación, crear un espacio de trabajo y procesar nuestros informes. Este último paso utiliza las otras variables declaradas en el archivo Secretos (mencionada anteriormente) y también utiliza algunas variables de contexto de GitHub.
El formato del nombre del espacio de trabajo será --, Así, por ejemplo, puede ser: faraday-pipelines-2020–11–03–68.
Nota importante: Faraday dispone de GitHub Custom Action que permite procesar también los informes. Sin embargo, esto no es obligatorio. En caso de que desee utilizar esta acción personalizada, el trabajo de carga debe definirse de la siguiente manera:
subir: necesidades: [scan] sigue corriendo: ubuntu-latestpasos:nombre: Obtener la fecha actual id: fecha correr: echo "::set-output name=fecha::$(fecha +'%Y-%m-%d')"- nombre: Descargar el informe Zap usos: acciones/descargar-artifact@master con: nombre: zap-informe camino: zap-informe- nombre: Descargar Bandit Report Artifact utilizaactions/download-artifact@master con: nombre: bandido-informe camino: bandido-informe- nombre: Cargar informes en Faraday usos: infobyte/gha-faraday-report-uploader@main con: anfitrión: ${{ secretos.FARADAY_HOST }} nombre de usuario: ${{ secretos.FARADAY_USERNAME }} contraseña: ${{ secretos.FARADAY_PASSWORD }} espacio de trabajo: ${{ github.event.repository.name }}-${{ steps.date.output.date }}-${{ github.run_number }} archivos: bandit-report/flaskapp_faraday_bandit.xml zap-report/zap-report.xml
Después de confirmar y empujar los cambios con nuestro nuevo ci.yml podemos ver el resultado de la ejecución pulsando en la pestaña Acciones de nuestro repositorio GitHub.

Si lo desea, puede descargar los informes en bruto generados por Bandido y Zap de OWASP (se adjuntan al resultado de la acción cuando se utiliza la función actions/upload-artifact@v2).
Ahora, si miras en tu Insights y Blog deberías ver tu nuevo espacio de trabajo creado en la Acción GitHub anterior ejecutándose de esta forma:

Por último, puede ver el espacio de trabajo del salpicadero:
Como puede ver, se han encontrado varias vulnerabilidades. Estas vulnerabilidades se pueden gestionar fácilmente como de costumbre con Faraday, como se puede ver en la siguiente imagen de informe de estado:
Como puede ver, es realmente fácil integrar Insights y Blog con nuestra función CI/CD utilizando algunas herramientas.
Como mencionamos en la introducción, mantener nuestras apps integradas con Faraday nos permitirá facilitar el trabajo del equipo de seguridad de la empresa, permitiéndonos detectar antes bugs de seguridad que podrían ser liberados en la versión de producción. Todo ello añadiendo simples pasos intermedios en el proceso CI/CD.
Este ejemplo ha sido creado enfocándose en las Acciones de GitHub, pero puede ser extendido para otras herramientas de CI/CD como Travis CI, Jenkins, Bitbucket Pipelines, entre otras.
Por último, pero no menos importante, para este ejemplo hemos utilizado sólo dos informes, pero puede utilizar todos los escáneres que desee porque Faraday es compatible con un amplia lista de informes. El único límite es tu imaginación.
Otros documentos Integración del clic de Faraday aquí
Enlaces útiles
Ejemplo repo utilizado + Script import_scan.py
Documentación de las acciones de GitHub
Sitio web oficial de OWASP Zap
cómo desplegar una aplicación python en Heroku
Como desplegar una aplicación flask en heroku usando GitHub Actions
Aplicación vulnerable utilizada en este ejemplo
Acción GitHub: Cargador Faraday
Descargue todos nuestros documentos sobre DevSecOps aquí

