DevSecOps

Juan Vera del Campo - juan.vera@professor.universidadviu.com

Hoy hablamos de...

  1. Desarrollo y Operaciones
  2. Etapas DevOps
  3. Resumen y referencias

Desarrollo y Operaciones

El problema

El código debe ser dinámico dinámico: los desarrolladores están constamentemente añadiendo funcionalidad y arreglando errores

  • ¿Cómo podemos automatizar el proceso de analizar la calidad del código?
  • ¿Cómo podemos reducir el tiempo de entrega de la nueva versión del código?
  • ¿Podemos hacer el código más seguro en esta etapa?

DevOps: metodología para que desarrollo, operaciones y seguridad colaboren desde las primeras etapas para automatizar el proceso que lleva desde la programación hasta la entrega derl código

https://www.edureka.co/blog/devops-tutorial

Problemas de los modelos tradicionales

center width:100%em

  • Demasiado tiempo entre desarrollo y despliegue
  • Tareas manuales no automatizadas
  • Varios equipos tienen que aceptas los cambios

Nuevo paradigma

center

CI/CD Continuous Integration / Continous Development

  • Compila código
  • Ejecuta tests
  • Despliega nuevas version de la aplicación
  • Comprueba que el sistema final no tiene problemas de seguridad
  • Flexible y adaptable a cambios
  • Feedback constante de los usuarios finales
  • Todo de forma automática

Cada cambio en el código se testea y despliega en producción en minutos

https://semaphoreci.com/blog/cicd-pipeline

Exigencias

  • Diseña el sistema de manera que admita versiones iterativas.
  • Métricas que ayuden a detectar problemas en tiempo real.
  • Desarrollo basado en tests para mantener siempre el código en un estado desplegable.
  • Monitoreo, registro y tolerancia a fallas por diseño.
  • Trabaja en pequeñas iteraciones. Por ejemplo, si desarrolla en ramas de características, no deberían vivir más de un día.
  • Uso de entornos de prueba similares a los de producción
  • Si lo desarrollas, lo ejecutas. Los equipos de ingeniería autónomos deben ser responsables de la calidad y la estabilidad del software que construyen
  • Los clientes tienen que poder aceptar cambios contantes
  • El desarrollo Ci/CD puede ser más caro que el tradicional

Buenas prácticas

  • Trata la rama "main" como si pudiese desplegarse en cualquier momento
  • Cada fallo de tests es un bug
  • Mejora los tests
  • No uses ramas de desarrollo enormes
  • Automatiza todo el despliegue:
    • Incluida la creación de infraestructura: terraform, ansible, kubernetes...

Y por supuesto, ¡introduce controles de seguridad en todo el proceso!

center

DevOps: herramientas

  • Repositorios de código (Github, Gitlab, Bitbucket, etc)
  • Infraestructura (Terraform, CloudFormation, etc)
  • CI/CD (Jenkins, Bamboo, CircleCI, TravisCI, etc)
  • Builds (Maven, Gradle, make, rake, etc)
  • Test (*unit, cucumber, protractor, etc)
  • Repositorio de artefactos (Nexus, Artifactory, Docker Hub,
    S3, etc)
  • Despliegue (Ansible, Puppet, Chef, etc)
  • Monitorización (NewRelic, AppDynamics, Sysdig, etc)
  • Logging (Splunk, ELK, etc)
  • Comunicación (Slack, HipChat, etc)

Etapas DevOps

Etapas

  • Build: en esta etapa se realiza la compilación de las unidades de código. Herramientas: Maven, Gradle...
  • Tests: la prueba de todas las unidades se realiza en esta etapa. Entonces, sabremos dónde exactamente el código tiene errores y, si se encuentran errores, no se continúa a las siguientes etapas. Herramientas: linters, Selenium, PYtest...
  • Integrar: en esta etapa, se integran todas las unidades de los códigos. Herramientas: Jenkins.
  • Despliegue: en esta etapa, el código se despliega en el entorno del cliente. AlEjemplos: AWS, Docker...
  • Operar: las operaciones se realizan en el código si es necesario.Herramienta: Kubernetes, OpenShift...
  • Monitor: en esta etapa, el monitoreo de la aplicación se realiza aquí en el entorno del cliente. Herramientas: Nagios, ELK, Splunk, Grafana...

center

Etapa 1: Build

Análisis estático de código: Static application security testing (SAST)

  • Linters
  • Compilación y gestión de errores de compilación
  • Detección de errores comunes de seguridad
  • Auditoría de librerías
  • Gestión de secretos
  • Herramientas: Brakeman (Ruby), SpotBugs+FindSecBugs (Java), Go AST (Go), Bandit (Python), Linters...

https://seguridad.prestigia.es/que-son-las-herramientas-sast-y-dast/
https://owasp.org/www-community/Source_Code_Analysis_Tools

Etapa 1: Build - linters

No corrigen errores, sino que usan formatos estandarizados para el código

  • Todo el equipo sigue las mismas reglas
  • Aumenta la legibilidad del código
  • Corrige algunos errores básicos
  • Pueden integrase en tu entorno de desarrollo

Ejemplos: black, Pylama, Flake8, Ruff...

https://twitter.com/svpino/status/1736037083276263563

Ejemplo: black

$ git clone https://github.com/NetSPI/django.nV ; cd django.nV
$ bpython3 -m pip install black
$ python3 -m black taskManager/views.py
$ git diff

center

Ejempo: pylama

$ git clone https://github.com/NetSPI/django.nV ; cd django.nV
$ python3 -m pip install pylama
$ python3 -m pylama taskManager/views.py
$ python3 -m pylama taskManager/views.py

taskManager/views.py:18:1 W0611 'codecs' imported but unused [pyflakes]
taskManager/views.py:161:9 W0612 local variable 'proj' is assigned to but never used [pyflakes]
taskManager/views.py:821:101 E501 line too long (151 > 100 characters) [pycodestyle]

Pueden ignorarse errores determinados:

$ python3 -m pylama -i E501 taskManager/views.py

taskManager/views.py:18:1 W0611 'codecs' imported but unused [pyflakes]
taskManager/views.py:161:9 W0612 local variable 'proj' is assigned to but never used [pyflakes]

También pueden integrarse en tu entorno de desarrollo para que haga las comprobaciones siempre:

center

Etapa 1: Build - Análisis estático de código (SAST)

Análisis estático: Static Application Security Testing

  • Análisis automático del código antes de compilarlo
  • Encuentra errores comunes: algoritmos que no deben usarse, estructuras que pueden crear un buffer overflow, variables usadas antes de asignarse...
  • Puede tener falsos positivos
  • No encontrará errores en la lógica del código
Lenguaje Herramienta SAST
Python bandit
Ruby Brakeman
Comerciales SonarQube
Secretos Github secrets, Trufflehog, git-secrets, detect-secrets...

Ejemplo: bandit analiza errores comunes en Python

git clone https://github.com/NetSPI/django.nV ; cd django.nV
python3 -m pip install bandit
bandit -r .

center

Ejemplo: SonarQube

center

El fiasco CrowdStrike y SAST

center

https://twitter.com/Perpetualmaniac/status/1814376668095754753
https://www.nytimes.com/2024/07/19/business/microsoft-outage-cause-azure-crowdstrike.html

Análisis estático - auditoría de librerías

  • Estas herramientas comprueban en una base de datos si la librería usada tiene alguna vulnerabilidad conocida -> ¡No analizan la librería!
  • ¿Es posible actualizar la librería o asumimos el riesgo?
  • No detectan vulnerabilidades automáticamente: se tiene que analizar periódicamente con bases de datos actualizadas
Lenguaje Herramienta de análisis de librerías
JS Retirejs/npm audit/AuditJS
Python Safety
Ruby Bundler audit/Chelsea
PHP Composer
Java OWASP dependency checker

Ejemplo: Safety analiza librerías Python

git clone https://github.com/NetSPI/django.nV ; cd django.nV
python3 -m pip install safety
python3 -m safety check -r requirements.txt --save-json safety-resuls.json

center

Ejemplo: Pip audit

git clone https://github.com/NetSPI/django.nV
python3 -m pip pip-audit
pip-audit -r ./requirements.txt

center

Ejemplo: npm audit (ya incluido con node)

https://github.com/SasanLabs/VulnerableApp-facade
cd VulnerableApp-facade/facade-app
npm audit

center

Ejemplo: Github Dependabot

Dependabot es un servicio que puedes activar en la configuración de tu proyecto en GitHub

Ejemplos de librerías maliciosas:

https://twitter.com/feross/status/1672401333893365761

Análisis estático - secretos

Errores comunes:

  • Archivos de configuración que no deberían subirse a un repositorio
  • Secretos hardcoded en el código fuente

https://www.wiz.io/academy/secret-scanning#scanning-for-secrets-with-wiz-85

Ejemplo: secretos en archivos de configuración

center

Ejemplo: secretos en código fuente

center

Utiliza detectores de contraseñas/tokens de seguridad:

  • Basados en patrones/regex: reconocen errores comunes como poner la contraseña en un parámetro función, o variables llamadas aws_token
  • Basados en entropía: reconocen "el aspecto" de una contraseña

Ten en cuenta que ambos métodos pueden tener falsos positivos

center

https://cybenari.com/2024/08/whats-the-worst-place-to-leave-your-secrets/

Tool History Regex/entropy FP handling Custom regex Language CI/CD Comments
git-secrets No regex yes yes shell scripts No -
Trufflehog yes both - yes python yes no
gitrob yes regex no yes ruby no no
repo-security-scanner yes regex@yes yes golang yes - -
git-hound - regex no yes golang - -
surch yes regex no yes python no -

Ejemplo: trufflehog

$ wget https://github.com/trufflesecurity/trufflehog/releases/download/v3.81.8/trufflehog_3.81.8_linux_amd64.tar.gz
$ tar -xvf trufflehog_3.81.8_linux_amd64.tar.gz trufflehog
$ chmod +x trufflehog
$ ./trufflehog filesystem --directory=.
$ ./trufflehog github --repo=https://github.com/dustin-decker/secretsandstuff

Nota: esto busca contraseñas en el propio archivo de trufflehog, a ti te interesará buscarlas en tu código

center

Ejemplo: deepfence

docker run --rm -v `pwd`:/source deepfenceio/deepfence_secret_scanner --local /source --output json

center

Con este ejemplo vemos también que podemos ejecutar algunas de las herramientas con docker. Veremos en la siguiente sesión que esto es muy deseable

Ejemplo: Github

Servicios ofrecidos por Github en sus repositorios

  • Dependabot: análisis de librerías
  • Code scanning: SAST para errores comunes
  • Secret scanning: patterns

Ejemplo: https://github.com/Juanvvc/sMSD/security (Nota: necesitas permisos)

Etapa 2: Tests

  • ¿Cuál es tu input?
    • ¿Qué pasa si algunos de los parámetros no esá presente, o tiene un tipo no esperado, o está fuera de rango?
  • ¿Cuál es la lógica?
    • Modificación de la entrada por otros elementos
    • Código esperando entrada del usaurio
    • Salidas sin control, o nulas
    • Timeouts para las salida
    • ¿Están todos los posibles casos cubiertos?
    • ¿Son relevantes todos los casos?
  • Interacciones con los datos: CRUD
    • ¿Autorización para las acciones?
    • ¿Puedes distinguir entre no autorizado, errores o datos que no existen?
  • Bucles
    • ¿Siempre acaban?
    • ¿Salen bien en caso de error?

Hris Koleva en twitter

Tests unitarios

import unittest
from code.my_calculations import Calculations

class TestCalculations(unittest.TestCase):

    def test_sum(self):
        calculation = Calculations(8, 2)
        self.assertEqual(calculation.get_sum(), 10, 'The sum is wrong.')

    def test_diff(self):
        calculation = Calculations(8, 2)
        self.assertEqual(calculation.get_difference(), 6, 'The difference is wrong.')

    def test_product(self):
        calculation = Calculations(8, 2)
        self.assertEqual(calculation.get_product(), 16, 'The product is wrong.')

    def test_quotient(self):
        calculation = Calculations(8, 2)
        self.assertEqual(calculation.get_quotient(), 4, 'The quotient is wrong.')

if __name__ == '__main__':
    unittest.main() 

https://www.dataquest.io/blog/unit-tests-python/

Test Coverage

center 10em

https://artoftesting.com/test-coverage

  • ¿Qué porcentaje del código cubren nuestros tests? Ejemplo: https://coverage.readthedocs.io/en/7.5.3/
  • ¿Qué portentaje de las amenazas detectadas durante el diseño cubren los tests?
  • ¿Se testean todos los casos de uso de la aplicación?

center

Etapa 4: Dynamic Application Security Testing DAST

  • Explora vulnerabilidades conocidas de las aplicación en ejecución
  • Ejemplos:
    • uso de protocolos http en vez de https
    • configuración inadecuada del servidor
    • puertos abiertos
    • Compliance

https://about.gitlab.com/blog/2019/08/12/developer-intro-sast-dast/
https://realm3ter.medium.com/analyzing-javascript-files-to-find-bugs-820167476ffe
https://www.gb-advisors.com/es/pruebas-de-seguridad-de-aplicaciones-ast-sast-dast-e-iast/

center

https://blog.51sec.org/2018/12/from-devops-to-devsecops-topics.html

Etapa 4: despliegue

Manejo de secretos:

  • AWS Secret Management
  • Azure Key Vault
  • Secret Manager (GCP)
  • GitHub secret scanning

https://gist.github.com/win3zz/0a1c70589fcbea64dba4588b93095855

Etapa 4: despliegue: análisis dinámico de código

  • Analiza vulnerabilidades de las aplicaciones en funcionamiento
  • Ejemplos: puertos cerrados, protocolos HTTPS para todo, configuraciones correctas...

Algunas herramientas:

Infrastructure-as-a-code

  1. Ejecuta terraform para desplegar dockers/máquinas virtuales
  2. Ejecuta ansible para configurar las máquinas desplegadas
  3. Ejecuta testeos con inspec

Terraform

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

provider "aws" {
  region  = "us-west-2"
}

resource "aws_instance" "app_server" {
  ami           = "ami-830c94e3"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleAppServerInstance"
  }
}

Ansible

- name: Playbook to install nginx
  hosts: sandbox
  remote_user: root
  become: yes

  # We are checking avaibility of nginx binary at a specific location
  tasks:
    - name: check if nginx installed
      stat:
        path: /usr/sbin/nginx
      register: stat_nginx

    - name: get nginx version
      command: nginx -v
      register: nginx_version
      when: stat_nginx.stat.exists

    - name: Print version
      debug:
        msg: "{{ nginx_version.stderr }}"
      when:
        - nginx_version is defined
        - stat_nginx.stat.exists

    - name: install nginx if not exist
      apt:
        name: nginx
        state: present
        update_cache: true
      when: not stat_nginx.stat.exists

https://www.redhat.com/sysadmin/harden-new-system-ansible

Inspec

describe file('/etc/ssh/sshd_config') do
    it { should exist }
    it { should be_file }
    it { should be_owned_by 'root' }
    its('content') { should match 'PasswordAuthentication no' }
end

describe file('/etc/pam.d/password-auth') do
  its('content') { 
      should match(/^\s*password\s+requisite\s+
        pam_pwquality\.so\s+(\S+\s+)*try_first_pass/)
  }
  its('content') {
      should match(/^\s*password\s+requisite\s+
        pam_pwquality\.so\s+(\S+\s+)*retry=[3210]/)
  }
end

Resumen y referencias

Referencias

¡Gracias!

El 19 de Julio de 2024, un programador olvidó comprobar si un puntero era NULL... en un driver de sistema como es CrowdStrike. El asunto dejó decenas de miles de PCs inservibles El error se podría haber evitado con herramientas de análisis de la calidad de código

Fíjate: el comando simplemente examina el archivo de requisitos, no el código Safety tiene una versión gratuita con vulnerabilidades >30 days, y otra de comercial con vulnerabilidades recientes

Comic: https://twitter.com/DZoneInc/status/1361420207793659904

Ejemplo de: > https://cybenari.com/2024/08/whats-the-worst-place-to-leave-your-secrets/

Ejemplo de: > https://cybenari.com/2024/08/whats-the-worst-place-to-leave-your-secrets/

Observa que trufflehog tiene diferentes detectores filesystem gitlab, token... trufflehog --help trufflehog filesystem --help trufflehog filesystem --directory=mydir