Docker: Lista De Materiales De Software O Software Bill Of Materials (SBOM)
Software Bill Of Materials (SBOM), es un inventario de los componentes de software y dependencias de un sistema, información de dichos componentes y la relación entre ellos. Este inventario se mantiene en un formato que es fácilmente legible por máquinas. Últimamente se han visto muchas vulnerabilidades relacionadas con la cadena de suministro de dependencias, una de las más sonadas el famoso log4shell entre otras. Cuando aparece una vulnerabilidad de este tipo, la pregunta es ¿Estamos afectado por dicha vulnerabilidad? ¿Alguno de nuestros sistemas usa la librería X? Y Docker nos puede ayudar.
La única forma de poder responder a este tipo de preguntas con cierta confianza es manteniendo el inventario, actualizado, de los componentes y dependencias que nuestros sistemas usan. Hay que tener en cuenta también que dicho inventario no sólo contenga los componentes y dependencias usadas directamente en nuestros sistemas, sino también las dependencias heredadas por dichos componentes y dependencias, también conocidas como dependencias transitivas.
Aunque SBOM no es algo nuevo, se puso muy de moda el año pasado cuando la Casa Blanca lanzó una orden ejecutiva en la requería que cualquier empresa que hiciera negocios con el gobierno norteamericano (venta de software, desarrollo o venta de licencias de uso) fuera capaz de proveer de esta lista de materiales con todos los componentes del software. De esta forma han sido muchas de las empresas que han incluido la posibilidad de la creación de SBOMs en sus herramientas, entre ellas Docker, dentro de su producto Docker Desktop.
Figura 1: Docker. Lista de Materiales de Software
o Software Bill Of Materials (SBOM)
La única forma de poder responder a este tipo de preguntas con cierta confianza es manteniendo el inventario, actualizado, de los componentes y dependencias que nuestros sistemas usan. Hay que tener en cuenta también que dicho inventario no sólo contenga los componentes y dependencias usadas directamente en nuestros sistemas, sino también las dependencias heredadas por dichos componentes y dependencias, también conocidas como dependencias transitivas.
Aunque SBOM no es algo nuevo, se puso muy de moda el año pasado cuando la Casa Blanca lanzó una orden ejecutiva en la requería que cualquier empresa que hiciera negocios con el gobierno norteamericano (venta de software, desarrollo o venta de licencias de uso) fuera capaz de proveer de esta lista de materiales con todos los componentes del software. De esta forma han sido muchas de las empresas que han incluido la posibilidad de la creación de SBOMs en sus herramientas, entre ellas Docker, dentro de su producto Docker Desktop.
En la versión 4.7.0, justo después de la publicación de la segunda la edición de nuestro libro Docker: SecDevOps, Docker añadió un plugin por defecto que permite la generación de ficheros SBOM y de los que vamos a ver algunos ejemplos, que ya hemos visto un poco qué es SBOM y por qué es importante.
Una cosa para recalcar, como se comentó antes, esto no es algo nuevo, y además tampoco es un estándar, por lo que existen varias iniciativas y formatos. Aunque no son los únicos que existen, los siguientes son los formatos que más fuerza o repercusión tienen actualmente:
- SPDX (Software Package Data Exchange), cuyo principal promotor es la Linux Foundation. Actualmente existen muchas herramientas que permite generar el SBOM en este formato.
- CycloneDX, éste tiene el apoyo de varias empresas y organizaciones, entre ellas OWASP. Al igual que con SPDX, existen muchas herramientas que permite generar el SBOM en este formato.
- SWID (Software Identification tags), este es un formato estandarizado en XML que identifica y contextualiza los componentes de un producto de software. Ojo, este no es un estándar SBOM, pero sí es un formato estandarizado (ISO/IEC 19770-2:2015). Al igual que los anteriores existen herramientas para la generación de ficheros SBOM en este formato.
Como comenté anteriormente, en la versión 4.7.0, Docker añadió una opción nueva (realmente un plugin) al comando *docker* llamada *sbom*. Este plugin usa por detrás un proyecto de Anchore llamado [syft](https://github.com/anchore/syft). Éste analiza las capas de la imagen y extrae la información sobre que comoponentes hay en cada capa. Si ejecutamos dicho comando obtendremos la siguiente salida:
$ docker sbom
Usage: docker sbom [OPTIONS] COMMAND
View the packaged-based Software Bill Of Materials (SBOM) for an image.
EXPERIMENTAL: The flags and outputs of this command may change.
Leave feedback on https://github.com/docker/sbom-cli-plugin.
Examples:
docker sbom alpine:latest a summary of discovered packages
docker sbom alpine:latest --format syft-json show all possible cataloging details
docker sbom alpine:latest --output sbom.txt write report output to a file
docker sbom alpine:latest --exclude /lib --exclude '**/*.db' ignore one or more paths/globs in the image
Options:
-D, --debug show debug logging
--exclude stringArray exclude paths from being scanned using a glob expression
--format string report output format, options=[syft-json cyclonedx-xml cyclonedx-json
github-0-json spdx-tag-value spdx-json table text] (default "table")
--layers string [experimental] selection of layers to catalog, options=[squashed all] (default
"squashed")
-o, --output string file to write the default report output to (default is STDOUT)
--platform string an optional platform specifier for container image sources (e.g. 'linux/arm64',
'linux/arm64/v8', 'arm64', 'linux')
--quiet suppress all non-report output
-v, --version version for sbom
Commands:
version Show Docker sbom version information
Run 'docker sbom COMMAND --help' for more information on a command.
an image argument is required
Dicho plugin permite la generación de ficheros SBOM en formato SPDX y CycloneDX. Veamos a continuación la salida por defecto que se produciría sobre una imagen Alpine: $ docker sbom alpine
Syft v0.43.0
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [14 packages]
NAME VERSION TYPE
alpine-baselayout 3.2.0-r16 apk
alpine-keys 2.3-r1 apk
apk-tools 2.12.7-r0 apk
busybox 1.33.1-r3 apk
ca-certificates-bundle 20191127-r5 apk
libc-utils 0.7.2-r3 apk
libcrypto1.1 1.1.1l-r0 apk
libretls 3.3.3p1-r2 apk
libssl1.1 1.1.1l-r0 apk
musl 1.2.2-r3 apk
musl-utils 1.2.2-r3 apk
scanelf 1.3.2-r0 apk
ssl_client 1.33.1-r3 apk
zlib 1.2.11-r3 apk
En este caso se puede ver la lista de los componentes de la imagen *alpine:latest*. Ahora veamos el mismo ejemplo, pero en formato SPDX: $ docker sbom --format spdx alpine
Syft v0.43.0
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [14 packages]
SPDXVersion: SPDX-2.2
DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: alpine-latest
DocumentNamespace: https://anchore.com/syft/image/alpine-latest-b478dc4d-bced-406a-adf9-6f7b7ea6d231
LicenseListVersion: 3.16
Creator: Organization: Anchore, Inc
Creator: Tool: syft-[not provided]
Created: 2022-04-15T20:19:57Z
##### Package: alpine-baselayout
PackageName: alpine-baselayout
SPDXID: SPDXRef-Package-apk-alpine-baselayout-ed18f2a986e77aab
PackageVersion: 3.2.0-r16
PackageDownloadLocation: NOASSERTION
FilesAnalyzed: false
PackageLicenseConcluded: GPL-2.0-only
PackageLicenseDeclared: GPL-2.0-only
PackageCopyrightText: NOASSERTION
ExternalRef: SECURITY cpe23Type cpe:2.3:a:alpine-baselayout:alpine-baselayout:3.2.0-r16:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:alpine-baselayout:alpine_baselayout:3.2.0-r16:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:alpine_baselayout:alpine-baselayout:3.2.0-r16:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:alpine_baselayout:alpine_baselayout:3.2.0-r16:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:alpine:alpine-baselayout:3.2.0-r16:*:*:*:*:*:*:*
ExternalRef: SECURITY cpe23Type cpe:2.3:a:alpine:alpine_baselayout:3.2.0-r16:*:*:*:*:*:*:*
ExternalRef: PACKAGE_MANAGER purl pkg:alpine/[email protected]?arch=x86_64&upstream=alpine-baselayout&distro=alpine-3.14.2
##### Package: alpine-keys
...
La salida es mucho más larga, pero a modo de ejemplo se puede ver uno de los componentes encontrados, con nombre, licencia, referencias externas, etcétera. También es posible generar la salida en formato *json*: $ docker sbom --format spdx-json alpine
Syft v0.43.0
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [14 packages]
{
"SPDXID": "SPDXRef-DOCUMENT",
"name": "alpine-latest",
"spdxVersion": "SPDX-2.2",
"creationInfo": {
"created": "2022-04-15T21:15:23.057754Z",
"creators": [
"Organization: Anchore, Inc",
"Tool: syft-[not provided]"
],
"licenseListVersion": "3.16"
},
"dataLicense": "CC0-1.0",
"documentNamespace": "https://anchore.com/syft/image/alpine-latest-2ea1fa9e-099e-4939-bdd8-d41fab29f1b0",
"packages": [
{
"SPDXID": "SPDXRef-ed18f2a986e77aab",
...
Para ver la salida en formato CycloneDX: $ docker sbom --format cyclonedx alpine
Syft v0.43.0
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [14 packages]
[0000] WARN unable to convert relationship from CycloneDX 1.3 JSON, dropping:
{From:Pkg(name="musl" version="1.2.2-r3" type="apk" id="304c2239a7d1d6b7")
To:Location<RealPath="/lib/ld-musl-x86_64.so.1"
...
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.4"
serialNumber="urn:uuid:faaf4f40-e332-4f0e-8acc-3fadcae62d25" version="1">
<metadata>
<timestamp>2022-04-15T17:17:00-04:00</timestamp>
<tools>
<tool>
<vendor>anchore</vendor>
<name>syft</name>
<version>[not provided]</version>
</tool>
</tools>
<component bom-ref="e33e1cadf7cfbd1e" type="container">
<name>alpine:latest</name>
<version>sha256:a2f19fdc3f78ddc201c5bb37e302fed8b3487695056215b5577113d3938196bf</version>
</component>
</metadata>
<components>
<component type="library">
<publisher>Natanael Copa <[email protected]></publisher>
<name>alpine-baselayout</name>
<version>3.2.0-r16</version>
<description>Alpine base dir structure and init scripts</description>
<licenses>
<license>
<id>GPL-2.0-only</id>
</license>
</licenses>
<cpe>cpe:2.3:a:alpine-baselayout:alpine-baselayout:3.2.0-r16:*:*:*:*:*:*:*</<pe>
<purl>pkg:alpine/[email protected]?arch=x86_64&upstream=alpine-baselayout&distro=alpine-3.14.2</purl>
<externalReferences>
<reference type="distribution">
<url>https://git.alpinelinux.org/cgit/aports/tree/main/alpine-baselayout</url>
</reference>
</externalReferences>
<properties>
<property name="syft:package:foundBy">apkdb-cataloger</property>
<property name="syft:package:metadataType">ApkMetadata</property>
<property name="syft:package:type">apk</property>
<property name="syft:cpe23">cpe:2.3:a:alpine-baselayout:alpine_baselayout:3.2.0-r16:*:*:*:*:*:*:*</property>
<property name="syft:cpe23">cpe:2.3:a:alpine_baselayout:alpine-baselayout:3.2.0-r16:*:*:*:*:*:*:*</property>
<property name="syft:cpe23">cpe:2.3:a:alpine_baselayout:alpine_baselayout:3.2.0-r16:*:*:*:*:*:*:*</property>
<property name="syft:cpe23">cpe:2.3:a:alpine:alpine-baselayout:3.2.0-r16:*:*:*:*:*:*:*</property>
<property name="syft:cpe23">cpe:2.3:a:alpine:alpine_baselayout:3.2.0-r16:*:*:*:*:*:*:*</property>
<property name="syft:location:0:layerID">sha256:e2eb06d8af8218cfec8210147357a68b7e13f7c485b991c288c2d01dc228bb68</property>
<property name="syft:location:0:path">/lib/apk/db/installed</property>
<property name="syft:metadata:gitCommitOfApkPort">8a8c96a0ea2fcd824c361aa4438763fa33ee8ca0</property>
<property name="syft:metadata:installedSize">413696</property>
<property name="syft:metadata:originPackage">alpine-baselayout</property>
<property name="syft:metadata:pullChecksum">Q1UJtB9cNV4r+/VbxySkEei++qbho=</property>
<property name="syft:metadata:pullDependencies">/bin/sh so:libc.musl-x86_64.so.1</property>
<property name="syft:metadata:size">20716</property>
</properties>
</component>
...
...
Como se pueden ver los campos generados son distintos que SPDX y el formato, por defecto, es XML, pero al final la información que se recolecta es prácticamente la misma. También es posible la generación en formato *json*: $ docker sbom --format cyclonedx-json alpine
Syft v0.43.0
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [14 packages]
[0000] WARN unable to convert relationship from CycloneDX 1.3 JSON, dropping: {From:Pkg(name="musl" version="1.2.2-r3" type="apk" id="304c2239a7d1d6b7") To:Location<RealPath="/lib/ld-musl-x86_6
...
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:95cef6a2-edcb-4b82-91a4-3ed026f1670f",
"version": 1,
"metadata": {
"timestamp": "2022-04-15T17:21:34-04:00",
"tools": [
{
"vendor": "anchore",
"name": "syft",
"version": "[not provided]"
}
],
"component": {
"bom-ref": "e33e1cadf7cfbd1e",
"type": "container",
"name": "alpine:latest",
"version": "sha256:a2f19fdc3f78ddc201c5bb37e302fed8b3487695056215b5577113d3938196bf"
}
},
"components": [
{
"type": "library",
"publisher": "Natanael Copa \[email protected]\u003e",
"name": "alpine-baselayout",
"version": "3.2.0-r16",
"description": "Alpine base dir structure and init scripts",
"licenses": [
{
"license": {
"id": "GPL-2.0-only"
}
}
],
"cpe": "cpe:2.3:a:alpine-baselayout:alpine-baselayout:3.2.0-r16:*:*:*:*:*:*:*",
"purl": "pkg:alpine/[email protected]?arch=x86_64\u0026upstream=alpine-baselayout\u0026distro=alpine-3.14.2",
"externalReferences": [
{
"url": "https://git.alpinelinux.org/cgit/aports/tree/main/alpine-baselayout",
"type": "distribution"
}
],
"properties": [
{
"name": "syft:package:foundBy",
"value": "apkdb-cataloger"
},
{
"name": "syft:package:metadataType",
...
La lista de los formatos soportados actualmente son: * syft-json
* cyclonedx-xml
* cyclonedx-json
* github-0-json
* spdx-tag-value
* spdx-json
* table (formato por defecto)
* text
Si en vez mandar el contenido del fichero a la consola o salida estándar, queréis que se guarde en un fichero, se puede usar la opción -o o --output: $ docker sbom --format spdx-json -o alpine.json alpine
Syft v0.43.0
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [14 packages]
La inclusión de este plugin en Docker está en modo experimental y puede que en futuras versiones éste cambie. Si tienes que generar SBOMs en entornos de producción, se podría usar la herramienta syft directamente. Esta herramienta es mucho más completa que lo que ofrece actualmente el plugin de Docker. Happy Hacking!
Autor: Rafael Troncoso (@tuxotron) es Senior Software Engineer en SAP Concur, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps" además del blog CyberHades. Puedes contactar con Rafael Troncoso en MyPublicInbox.
Via: www.elladodelmal.com
Docker: Lista De Materiales De Software O Software Bill Of Materials (SBOM)
Reviewed by Zion3R
on
0:50
Rating: