In this article
Tres pasos para proteger las imágenes de contenedor
Guía de seguridad de contenedores creada con Docker
Seguridad de imágenes de contenedor con Docker
Si alguna vez analizaste una imagen de contenedor en busca de vulnerabilidades, probablemente encontraste más de unos cuantos problemas: quizá cientos o incluso miles. Esta guía Seguridad de contenedores para equipos de desarrollo, escrita en colaboración por Snyk y Docker, se centra en la imagen de contenedor y el software que incluye. Puedes descargar aquí la versión en PDF de esta guía de seguridad de contenedores.
Comienza con una mirada a la importancia de la seguridad de los contenedores. Los contenedores son cada vez más populares, pero presentan riesgos de seguridad que pueden exponer a las empresas a pérdidas de productividad, reducción de ventas e incluso multas de millones de dólares. Este artículo describe nuestro proceso de tres pasos para crear imágenes de contenedor seguras. Regístrate para obtener una cuenta gratuita de Snyk y encontrar y corregir fácilmente vulnerabilidades en imágenes de Docker y bibliotecas de código abierto.
Tres pasos para proteger las imágenes de contenedor
Como señalamos antes, la seguridad de las imágenes de contenedor no es una única área de interés: abarca a los equipos de desarrollo, seguridad y operaciones. Hay varios aspectos de seguridad que se aplican a los contenedores
La propia imagen de contenedor y el software que contiene
La interacción entre un contenedor, el sistema operativo anfitrión y otros contenedores en el mismo anfitrión
El propio sistema operativo anfitrión
Aspectos relacionados con las redes y el almacenamiento de contenedores
La seguridad en tiempo de ejecución, a menudo en clústeres de Kubernetes

Cada uno de estos puntos merece una guía propia para abordarlo como corresponde, y todos, excepto el primero, ya cuentan con una o más guías. Esta guía se centra en la imagen de contenedor y el software que incluye.
A grandes rasgos, hay tres pasos clave para crear una imagen de contenedor segura:
Analizaremos cada uno de estos puntos con más detalle para ver cómo este enfoque puede ayudar a crear imágenes de contenedor seguras.
1. Protege tu código y sus dependencias
Es probable que una de las razones principales por las que creas un contenedor sea entregar tus aplicaciones nativas de la nube con mayor rapidez, y tus aplicaciones son la esencia de tu organización. Hace no tanto, la seguridad de las aplicaciones empezaba y terminaba con el código. Aunque los contenedores y otras prácticas de desarrollo modernas han ampliado el significado de «código de aplicación», esta área de interés sigue siendo importante.
Por suerte, esta es la parte de las imágenes de contenedor que los desarrolladores pueden controlar más directamente y, con suerte, la que mejor conocen. Aun así, no es sencillo identificar todas las dependencias de tu código ni determinar cómo corregir los problemas de seguridad. Si tienes acceso al código fuente, usa herramientas diseñadas específicamente para este propósito, como Snyk Open Source, para realizar análisis de composición de software (SCA) y pruebas de seguridad de aplicaciones estáticas (SAST) en tu código y sus dependencias. En las aplicaciones modernas, no es raro que las dependencias de código abierto de terceros representen la mayoría de las líneas de código de una aplicación.

Detectar problemas al principio del desarrollo e integrar herramientas de seguridad con tu código fuente permite automatizar este proceso, sin depender de la etapa de creación de contenedores. Es posible analizar un contenedor y algunos tipos de código, pero detectar estos problemas directamente en tus confirmaciones de Git, canalizaciones y repositorios probablemente se adapte mejor al proceso de trabajo de un desarrollador.
Empieza con Capture the Flag
Aprende a resolver desafíos de Capture the Flag viendo nuestro taller virtual introductorio a pedido.
2. Comienza con una imagen base mínima de una fuente confiable
¿Por qué son tan importantes las imágenes pequeñas?
La imagen base —la línea FROM de tu Dockerfile— es uno de los aspectos más importantes de la seguridad. Por suerte, muchos proveedores confiables ofrecen contenido que puedes usar fácilmente. Docker Hub es, por mucho, el punto de partida más popular para obtener imágenes base de contenedor.
Docker Hub tiene más de 3.8 millones de imágenes disponibles y más de 7 millones de repositorios. Es una plataforma muy activa y registra alrededor de 11 mil millones de descargas al mes. Algunas de estas imágenes son Official Images, que Docker publica como una selección curada de repositorios de código abierto de Docker y soluciones listas para usar.
Docker también ofrece imágenes publicadas por Verified Publishers. Estas imágenes de alta calidad son publicadas y mantenidas directamente por entidades comerciales que Docker verifica como Verified Publishers. Las pautas de Docker para estos proveedores verificados son un excelente punto de partida para definir tus propias prácticas recomendadas internas para imágenes de contenedor.

Es fácil ir a Docker Hub y encontrar una imagen pública que se adapte a tu caso de uso, pero debes prestar atención al origen de las imágenes que eliges. Del mismo modo que no descargarías ni instalarías software desde un sitio web no confiable, probablemente tampoco querrías usar imágenes subidas a Docker Hub por usuarios que no conoces y en quienes no confías.
Si usas imágenes que forman parte del programa Official de Docker, o si conoces y puedes verificar el origen y el contenido de imágenes de terceros —quizá con una herramienta como Notary para comprobar las firmas digitales—, tendrás cierto nivel de garantía de calidad. Pero, para reducir aún más la cantidad de vulnerabilidades y tener más control sobre lo que se incluye en tus contenedores, debes ir un paso más allá y elegir imágenes base mínimas que se ajusten a tus necesidades.
Por ejemplo, en la figura 3 de arriba se muestra un repositorio de Python. Sin duda, puedes crear tu aplicación de Python y casi con certeza funcionará. Esto se debe a que la imagen etiquetada en Docker Hub está diseñada para facilitar el trabajo en muchos casos de uso distintos y se mantiene bien. Sin embargo, hay más de 1000 imágenes de Python en este repositorio.
¿Deberías usar simplemente lo que incluye la fácil de recordar _python o hay imágenes más pequeñas que se adapten a tus necesidades y también reduzcan tu superficie de exposición a riesgos de seguridad_? Como quizá imaginas, casi seguro hay mejores opciones desde una perspectiva de seguridad.
El tamaño de las imágenes de contenedor importa, y no solo por la portabilidad y las descargas rápidas. La imagen etiquetada como python es fácil de usar porque incluye una cantidad considerable de bibliotecas del sistema operativo y paquetes de desarrollo preinstalados. Esto significa que probablemente funcionará muy bien con diversos proyectos y tendrá todo lo que necesitas para compilar código y dependencias; pero los analizadores de vulnerabilidades también pueden mostrar una larga lista de problemas por resolver.

Quizá te preguntes por qué ambas imágenes siguen teniendo vulnerabilidades, en especial vulnerabilidades de gravedad alta. Sin embargo, al revisar estas vulnerabilidades en particular, verás que forman parte de los paquetes del sistema operativo subyacente. Ninguna tiene una corrección disponible y no se conocen exploits activos. Además, como parte del proceso de verificación de proveedores de Docker, ambas imágenes se actualizaron con las versiones más recientes de todos sus paquetes en los últimos días, por lo que, de hecho, se mantienen bien.
También debemos considerar el contexto: a menudo, las vulnerabilidades que aparecen se encuentran en herramientas de desarrollo que probablemente querrías quitar de la versión de producción de tu imagen, como curl, bibliotecas de desarrollo o incluso shells y administradores de paquetes. Sin embargo, con el tiempo, es mucho más probable que el descubrimiento de nuevas vulnerabilidades afecte a la imagen de Python más grande que a la versión más ligera.
Ejemplo práctico de seguridad de imágenes de contenedor: selección de imágenes base
Como dijimos antes, «empieza con imágenes ligeras» es un consejo que puedes encontrar en cualquier lugar. Pero una de las razones por las que Docker y Snyk se asociaron es para ayudarte a pasar del consejo a la acción. La función integrada de análisis de vulnerabilidades de Docker Desktop puede encargarse de parte del proceso de selección de imágenes base.
Seguiremos con nuestro ejemplo de Python para ver cómo pasar de la imagen de Python a la imagen python:3-slim-buster usando la función de análisis de vulnerabilidades de Docker, con tecnología de Snyk. Si quieres, puedes seguir estos pasos en tu propio entorno.
Primero, comenzaremos con un caso sencillo y usaremos la imagen de Python para crear una imagen de contenedor muy simple. Este es el Dockerfile que usaremos:
FROM python
WORKDIR /app
COPY hello.py /app
CMD [“python3”, “hello.py”]No puede ser mucho más sencillo. El archivo hello.py contiene una sola instrucción print: (“Hello, World!”).
A continuación, crearemos la imagen y la analizaremos:
$> docker build -t hello-python .
[+] Building 67.4s (5/5) FINISHED
=> [internal] load build definition from Dockerfile 0.4s => => transferring dockerfile: 36B 0.1s => [internal] load .dockerignore 0.4s => => transferring context: 2B 0.1s => [internal] load metadata for docker.io/library/python:latest 1.6s => FROM [1/1] FROM docker.io/library/python 65.1s
...
=> exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:3a92e9... 0.0s => => naming to docker.io/library/hello-python 0.0s
$> docker run hello-python
Hello, World!
$> docker scan hello-python -f Dockerfile
/ Analyzing docker dependencies for hello-python/Dockerfile
Organization: snyk-pmm Package manager: deb
Target file: Project name: Docker image: Base image:
Dockerfile docker-image|hello-python hello-python
python
Tested 431 dependencies for known issues, found 268 issues. Base Image Vulnerabilities Severity
python:latest 268 6 high, 34 medium, 228 low
Recommendations for base image upgrade:
Alternative image types
Vulnerabilities Severity
75 1 high, 10 medium, 64 low
Base Image
python:3-slim-buster
python:3.9-rc-slim-buster 75 1 high, 10 medium, 64 lowPrimero, observa que el resultado indica que se encontraron 431 dependencias y 268 problemas en la imagen. Omitimos las vulnerabilidades individuales para abreviar; las veremos en un momento. No agregamos nada interesante a la imagen base python, así que las 268 vulnerabilidades provienen de la base, como también puedes ver en el resultado.
Pero al final del resultado aparecen recomendaciones de imágenes base que pueden ayudar a mejorar nuestra postura de seguridad. En concreto, aparece la imagen python:3-slim-buster que mostramos antes. De hecho, así fue como llegamos a nuestra comparación inicial. Ya vemos que esta nueva imagen eliminará más del 70 % de las vulnerabilidades iniciales de la imagen de Python y reducirá el total a una vulnerabilidad de gravedad alta. Aun así, volveremos a crear y analizar la imagen para comprobarlo.
El Dockerfile solo requiere un cambio sencillo en la línea FROM. Guardaremos una copia aparte con el nombre Dockerfile.slim.
FROM python
WORKDIR /app
COPY hello.py /app
CMD [“python3”, “hello.py”]Después, podemos volver a crear y analizar la imagen con una etiqueta slim para mantenerlas separadas:
```
$> docker build -t hello-python:slim . -f Dockerfile.slim
[+] Building 21.0s (8/8) FINISHED
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile.slim 0.1s
=> => transferring dockerfile: 135B 0.0s
=> [internal] load metadata for docker.io/library/python:3-slim-buster 11.5s
...
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:63768699. 0.0s
=> => naming to docker.io/library/hello-python:slim 0.0s
$> docker run hello-python:slim
Hello, World!
$> docker scan hello-python:slim -f Dockerfile.slim
Package manager: deb
Target file: Dockerfile.slim
Project name: docker-image hello-python
Docker image: hello-python:slim
Base image: python:3-slim-buster
Licenses: enabled
Tested 94 dependencies for known issues, found 75 issues.
According to our scan, you are currently using the most secure version of the selected base image
```Esta vez, puedes ver que el análisis completo encontró solo 94 dependencias y una vulnerabilidad de gravedad alta. Así es como Docker y Snyk pueden guiarte hacia mejores imágenes base. Como quizá imaginas, no ofrecemos cobertura para todas las imágenes de Docker Hub, pero sí cubrimos la mayoría de las imágenes base oficiales más populares.
Seguridad de contenedores centrada en los desarrolladores
Snyk encuentra y corrige automáticamente vulnerabilidades en imágenes de contenedores y cargas de trabajo de Kubernetes.
3. Administra todas las capas entre la imagen base y tu código
Analizamos en detalle las imágenes base porque requieren consideraciones especiales. Al crear tus propias capas encima, heredas todo lo que incluye la imagen base, y una imagen ligera suele reducir la carga de seguridad. Pero ¿qué pasa con todas las capas que agregas al contenedor? Si comienzas con una imagen ligera, es probable que tengas que agregar herramientas y bibliotecas, además de tu código y distintos elementos que debes instalar para que todo funcione. También debes supervisarlos para detectar vulnerabilidades.
La buena noticia es que tienes control directo sobre estas capas intermedias, que abarcan todo lo que está después de la primera línea FROM y antes de las últimas líneas del Dockerfile, donde configuras la ejecución de tu código. Más específicamente, nos interesan los comandos RUN, COPY y ADD de los Dockerfiles, ya que son los que instalan elementos. En términos técnicos, tu código también podría estar en estas capas intermedias. Sin embargo, para este análisis lo llamaremos la capa final, principalmente porque ya abordamos el código en el paso 1.

Uno de los mayores desafíos para administrar las vulnerabilidades en estas capas intermedias es priorizar a qué prestar atención en las distintas etapas del ciclo de vida.
En cada etapa quizá necesites diferentes herramientas, pero a medida que las imágenes se acercan a producción, debes quitar todo lo que no sea absolutamente necesario para ejecutar tu aplicación. Si personalizas tus imágenes empezando con una base mínima y luego agregas tus herramientas, será muy fácil quitarlas después: solo tienes que eliminarlas del Dockerfile y volver a crear la imagen. O, mejor aún, puedes usar compilaciones de varias etapas para abarcar todas estas fases en un único proceso de compilación automatizado.
Priorizar las correcciones de vulnerabilidades de seguridad en contenedores
Dicho esto, aún encontrarás vulnerabilidades de seguridad y tendrás que decidir cómo abordarlas. En teoría, lo ideal es llegar a cero vulnerabilidades, pero en la práctica probablemente no sea factible ni valga la pena dedicarle el tiempo.
Te sugerimos comenzar con las etapas de trabajo tradicionales: desarrollo, pruebas y producción. Es probable que tus procesos de producción de software sean más complejos, pero puedes adaptarlos según sea necesario.
Comienza con las imágenes de desarrollo
Imágenes de desarrollo probablemente tendrán más vulnerabilidades en las capas intermedias porque suelen necesitar más herramientas y paquetes de soporte. La buena noticia es que, SI creas imágenes por etapas y tus imágenes de producción no incluyen todos estos elementos adicionales, quizá puedas ignorar muchas de las vulnerabilidades en esta etapa. Para tomar esta decisión, debes poder hacer un seguimiento de las dependencias instaladas en el contenedor y compararlas con lo que sabes que necesitas para tu ciclo de desarrollo interno. Es bastante normal que haya una vulnerabilidad en una biblioteca instalada como dependencia de otra dependencia, que a su vez depende de otra… debes poder determinar si basta con quitar uno de tus paquetes de desarrollo para resolver la vulnerabilidad.En el ejemplo siguiente, tenemos una aplicación Ruby. Es común que SQLite venga incluido con Ruby para simplificar el desarrollo, pero probablemente no usarías esa misma base de datos SQLite en producción. Si lo sabes y tienes los detalles adecuados del análisis de vulnerabilidades del contenedor, puedes decidir ignorar las vulnerabilidades de las bibliotecas que se instalan con SQLite durante el desarrollo. Veremos cómo el análisis de Docker proporciona esta información y otros detalles que simplifican mucho esta tarea.

Reduce las imágenes de prueba
Imágenes de prueba: en la práctica no son muy diferentes de las imágenes de desarrollo, al menos en cuanto a cómo considerar las vulnerabilidades. Si sabes que una vulnerabilidad forma parte de un paquete de prueba que no estará en la imagen de producción, puedes optar por ignorarla. Este es un buen momento para comparar los resultados del análisis con los de la etapa de desarrollo, sobre todo si decidiste ignorar alguna vulnerabilidad grave durante esa etapa. ¿Las vulnerabilidades de las imágenes de desarrollo realmente desaparecieron en las de prueba? Si es así, tu proceso está funcionando. Si no, quizá sea hora de volver a ajustar la imagen de desarrollo o los pasos de compilación.Deja listas tus imágenes de producción
Imágenes de producción: son las imágenes críticas, ya que realmente se ejecutarán en algún entorno y podrían estar expuestas al mundo exterior. Aun así, llegar a cero vulnerabilidades puede ser difícil, incluso si reduces la imagen y eliminas todo lo posible. En muchos casos, el objetivo es automatizar el proceso de lanzamiento. Sin duda, debes abordar las vulnerabilidades de alto riesgo, especialmente las que tienen exploits conocidos; pero una de las razones por las que también conviene analizar las imágenes de desarrollo y prueba es reducir las sorpresas cuando estés por lanzar. Si mitigaste los riesgos desde el principio, la función principal del análisis en producción será encontrar vulnerabilidades nuevas que aparezcan a última hora.
Veamos otro ejemplo para descubrir cómo puedes usar Docker y Snyk con las capas intermedias.
Ejemplo práctico: priorizar las correcciones de vulnerabilidades introducidas por el usuario
En este ejemplo, mostraremos algunas técnicas prácticas para las «capas intermedias» que puedes usar con las funciones de análisis de vulnerabilidades de Docker, impulsadas por Snyk. Primero, esta vez usaremos una aplicación un poco más interesante. Es una aplicación Ruby, aunque eso no es demasiado importante para estos ejercicios.
Aquí está nuestro Dockerfile:
```
FROM ruby:2.5.1
RUN apt-get update && \
apt-get install -y git vim && \
rm -rf/var/lib/apt/lists/*
RUN gem update --system 3.0.4 && \
gem install bundler -V '2.0.2'
WORKDIR /usr/src/app/alpha-blog
COPY . .
ENV BUNDLER VERSION 2.0.2
RUN bundle update && \
bundle install && \
rails db:setup && \
rails db:migrate
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```Sigue siendo un Dockerfile bastante sencillo, en el que agregamos varias capas sobre nuestra imagen base de Ruby:
La primera línea
RUNagrega un par de utilidades para el desarrollo local dentro de la imagenLuego actualizamos y preparamos los componentes principales de Ruby
Copiamos nuestro código mediante el comando
COPY . .Inicializamos nuestro proyecto Rails con los comandos
RUN bundle…
Si estás pensando «Instalar git y vim en una imagen parece una decisión extraña», tienes razón. No lo hagas. El laboratorio completo que mencionamos en la nota anterior explica el historial de esta imagen y por qué están aquí.
Aunque no es muy complicado entender lo que sucede, como puedes imaginar, cada una de estas líneas del Dockerfile termina instalando bastantes cosas, lo que podría agregar nuevas vulnerabilidades a nuestra imagen.
Podemos compilar esta imagen y probarla igual que antes:
```
$> docker build -t blog .
[+] Building 111.5s (11/11) FINISHED
.
.
.
=> [6/6] RUN bundle update && bundle install &&
rails db:setup && rails db:migrate 108.8s
=> exporting to image 1.6s
=> => exporting layers 1.6s
=> => writing image sha256:0b7c017032e301429...433c23a5 0.0s
=> => naming to docker.io/library/blog 0.0s
$> docker scan blog -f Dockerfile
Testing blog...
.
.
.
X High severity vulnerability found in bzip2
Description: Out-of-bounds Write
Info: https://snyk.io/vuln/SNYK-DEBIAN9-BZIP2-450801
Introduced through: bzip2@1.0.6-8.1, bzip2/libbz2-dev@1.0.6-8.l, imagemagick/libmagickcore-dev@8:6.9.7.4+dfsg-11+deb9u6,meta-common-packages@meta
From: bzip2@1.0.6-8.1
From: bzip2/libbz2-dev@1.0.6-8.1
From: imagemagick/libmagickcore-dev@8:6.9.7.4+dfsg-ll+deb9u6>imagemagick/libmagickcore-6.q16-dev@8:6.9.7.4+dfsg-1l+deb9u6 › bzip2/libbz2-devel.0.6-8.1
and 1 more..
Introduced by your base image (ruby:2.5.1)
X High severity vulnerability found in apt/libapt-pkg5.0
Description: Arbitrary Code Injection
Info: https://snyk.io/vuln/SNYK-DEBIAN9-APT-407402
Introduced through: apt/libapt-pkg5.0@1.4.8, apt@l.4.8
From: apt/libapt-pkg5.001.4.8
From: apt@l.4.8 > apt/libapt-pkg5.001.4.8
From: apt@l.4.8
Introduced by your base image (ruby:2.5.1)
Fixed in: 1.4.9
Organization: snyk-pmm
Package manager: deb
Target file: Dockerfile
Project name: docker-image|blog
Docker image: blog
Base image: ruby:2.5.1
Licenses: enabled
Tested 413 dependencies for known issues, found 871 issues.
Base Image Vulnerabilities Severity
ruby:2.5.1 867 48 high, 237 medium, 582 low
Recommendations for base image upgrade:
Minor upgrades
Base Image Vulnerabilities Severity
ruby:2.5 257 6 high, 34 medium, 217 low
Alternative image types
Base Image Vulnerabilities Severity
ruby:2.5-slim 53 0 high, 5 medium, 48 low
ruby:2.7.0-slim-buster 61 1 high, 8 medium, 52 low
ruby:2.7.0-preview3-slim-buster 63 1 high, 9 medium, 53 low
ruby:2.7.0-preview2-slim 63 1 high, 9 medium, 53 lowEstá claro que quien creó este Dockerfile no siguió nuestros consejos de la sección anterior: ¡871 vulnerabilidades, y nuestra imagen base ya comienza con 867! Tendremos que encontrar a esa persona y darle una copia de esta guía. Pero ahora nos interesa averiguar si agregamos vulnerabilidades con alguno de nuestros propios comandos del Dockerfile. La diferencia entre el total de problemas y los de la imagen base indica que hay al menos cuatro vulnerabilidades que debemos abordar.
El comando docker scan puede ayudarnos a acotar la búsqueda rápidamente, ya que ignora todas las vulnerabilidades de la imagen base mediante la opción –exclude-base. Aquí tienes otro análisis y un fragmento del resultado al excluir las vulnerabilidades de la imagen base:
La opción —exclude-base requiere incluir el Dockerfile como parte del análisis (la opción -f Dockerfile que hemos estado usando)
X High severity vulnerability found in curl/libcurl3
Description: Buffer Overflow
Info: https://snyk.io/vuln/SNYK-DEBIAN9-CURL-466505
Introduced through: curl@7.52.1-5+deb9u7, curl/libcurl4-openssl-dev@7.52.1-5+deb9u7, gitel:2.11.0-3+deb9u7
From: curl@7.52.1-5+deb9u7 > curl/libcurl3@7.52.1-5+deb9u7
From: curl/libcurl4-openssl-dev@7.52.1-5+deb9u7 › curl/libcurl3@7.52.1-5+deb9u7
From: curl@7.52.1-5+deb9u7
and 2 more..
Introduced in your Dockerfile by `RUN apt-get update && apt-get install -y git vim && rm -rf/var/lib/apt/lists/*`
Fixed in: 7.52.1-5+deb9u10
Organization: snyk-pmm
Package manager: deb
Target file: Dockerfile
Project name: docker-image|blog
Docker image: blog
Base image: ruby:2.5.1
Licenses: enabled
Tested 413 dependencies for known issues, found 70 issues.Esto es un poco más manejable: 70 problemas en lugar de 871. Si revisas la lista de vulnerabilidades detectadas, también verás una línea que comienza con «Introduced in your Dockerfile by». También tenemos la ruta de dependencias, que nos permite rastrear una vulnerabilidad hasta su origen, pero conocer el comando real del Dockerfile (en vez de una interpretación críptica del comando) nos lleva directamente al punto donde se introdujo.
Aun así, 70 vulnerabilidades son demasiadas para abordar de una sola vez.
A menudo, los equipos de seguridad y desarrollo quieren enfocarse primero en todas las vulnerabilidades corregibles de gravedad alta.
También podemos obtener ese nivel de detalle fácilmente con la opción de salida JSON y un poco de filtrado mediante la utilidad de línea de comandos JSON jq (ten en cuenta que jq admite sin problema saltos de línea dentro del comando):
```
$> docker scan blog -f Dockerfile --exclude-base --json | \
jq '[.vulnerabilities[]
| select(.nearestFixedInVersion)
| select(.severity == "high")
| { packageName,
dockerfileInstruction,
title,
severity,
version,
nearestFixedInVersion}]'
$> docker scan blog -f Dockerfile --exclude-base --json | \
jq '[.vulnerabilities[]
| select(.nearestFixedInVersion)
| select(.severity == "high")
| { packageName,
dockerfileInstruction,
title,
severity,
version,
nearestFixedInVersion}]'
[
{
"packageName": "curl",
"dockerfileInstruction": "apt-get install -y git vim",
"title": "Out-of-bounds Write",
"severity": "high",
"version": "7.52.1-5+deb9u7",
"nearestFixedInVersion": "7.52.1-5+deb9u13"
},
...
{
"packageName": "perl",
"dockerfileInstruction": "apt-get install -y git vim",
"title": "Integer Overflow or Wraparound",
"severity": "high",
"version": "5.24.1-3+deb9u4",
"nearestFixedInVersion": "5.24.1-3+deb9u7"
},
{
"packageName": "perl",
"dockerfileInstruction": "apt-get install -y git vim",
"title": "Buffer Overflow",
"severity": "high",
"version": "5.24.1-3+deb9u4",
"nearestFixedInVersion": "5.24.1-3+deb9u7"
},
{
"packageName": "perl",
"dockerfileInstruction": "apt-get install -y git vim",
"title": "Out-of-bounds Write",
"severity": "high",
"version": "5.24.1-3+deb9u4",
"nearestFixedInVersion": "5.24.1-3+deb9u7"
}
]
```¡Listo! En la vista final aparecen 36 vulnerabilidades, todas de gravedad alta y con una corrección disponible, junto con el comando del Dockerfile y la versión con la corrección. A partir de aquí, deberíamos poder corregirlas. Si no conoces el comando jq, esto puede parecer complejo. Aquí tienes un breve resumen de lo que hicimos, aunque jq es una herramienta muy potente y vale la pena dedicarle un poco de tiempo para aprender a usarla:
Para empezar, agregamos la opción de salida --json al comando docker scan y, luego, con jq, hicimos lo siguiente:
Seleccionamos solo las vulnerabilidades de la salida
Elegimos solo las vulnerabilidades que tienen una corrección disponible y las que tienen gravedad «high»
Simplificamos un poco la salida mostrando solo algunos campos de las vulnerabilidades
Seguridad de contenedores centrada en los desarrolladores
Snyk encuentra y corrige automáticamente vulnerabilidades en imágenes de contenedores y cargas de trabajo de Kubernetes.
Conclusiones
La seguridad de los contenedores es un tema amplio. Incluso si nos limitamos a la seguridad de las imágenes, hay varios vectores de seguridad que debemos examinar. Para proteger tus imágenes, ten en cuenta estos puntos clave:
Comienza con imágenes base de un proveedor de confianza. Usa firmas digitales para verificar su autenticidad.
Cuando sea posible, elige imágenes base mínimas que incluyan solo los paquetes básicos del sistema operativo y la versión del framework que prefieras; luego, agrega lo demás.
Revisa tus imágenes en busca de vulnerabilidades desde el principio y con frecuencia. Crea tus propias imágenes base aprobadas, mantenlas activamente y asegúrate de que pasen todos tus controles de seguridad; vuelve a analizarlas cada vez que crees imágenes nuevas.
Analiza en varias etapas del ciclo de vida del software: en el equipo local, en CI, en las imágenes almacenadas en registros y en los contenedores o pods que se ejecutan en tus clústeres.
Al elegir herramientas para realizar los análisis, no te limites a la lista de vulnerabilidades que ofrecen:
¿La herramienta irá más allá de reportar vulnerabilidades y te avisará si hay una imagen base más nueva o mejor que puedas usar?
Si una compilación falla porque se detectaron vulnerabilidades, ¿la herramienta les dará a los desarrolladores y equipos de DevOps suficiente información para corregir los problemas?
¿La herramienta ofrece la flexibilidad que necesitas para configurar tus controles de seguridad?
No existe una solución única para todos: es probable que tus desarrolladores necesiten más herramientas en una imagen de las que permitirías en producción, así que quizá uses imágenes distintas en cada etapa del ciclo de vida del desarrollo. La automatización, CI y los Dockerfiles que admiten estas etapas permiten establecer los controles de seguridad adecuados y equilibrar la seguridad con la productividad para obtener los mayores beneficios.
Para empezar a proteger tus imágenes de contenedores con Docker y Snyk, regístrate ahora!