Calidad y seguridad
A finales de 2021 se dio a conocer la vulnerabilidad Log4Shell en la muy extendida biblioteca Java Log4j. En muchas empresas empezó entonces una búsqueda de días: ¿está la biblioteca en alguno de nuestros productos y, en caso afirmativo, en qué versión? Quien tenía una lista de materiales de software respondió a la pregunta en minutos. Con el Cyber Resilience Act, esta lista de materiales pasa a ser obligatoria para los fabricantes.
Qué debe contener una SBOM
El CRA define la lista de materiales de software, en inglés Software Bill of Materials (SBOM), como un registro formal de los detalles y de las relaciones en la cadena de suministro de los componentes incluidos en el software de un producto. En la práctica, es una lista legible por máquina de todas las bibliotecas, paquetes y módulos. Para cada componente debe incluir como mínimo:
- el nombre y la versión,
- el fabricante o proveedor,
- un identificador único, normalmente como Package URL, por ejemplo
pkg:nuget/Newtonsoft.Json@13.0.3, - una suma de comprobación del archivo entregado,
- la licencia,
- las dependencias con otros componentes.
Lo que no debe incluir son las vulnerabilidades. Si una brecha afecta realmente a su producto se documenta por separado, por ejemplo en un documento VEX (Vulnerability Exploitability eXchange).
Qué exige el CRA y qué no
El anexo I, parte II, punto 1, exige una SBOM en un formato habitual legible por máquina que recoja, como mínimo, las dependencias de primer nivel. Forma parte de la documentación técnica y se entrega a la autoridad de vigilancia del mercado previa solicitud motivada. No tiene que publicarla. Si la pone a disposición de sus clientes, indique en la información para los usuarios dónde se encuentra. Hasta ahora, el reglamento no prescribe un formato fijo; la Comisión puede establecerlo mediante un acto de ejecución.
Ya hoy, la directriz técnica TR-03183-2 de la BSI (Oficina Federal de Seguridad de la Información de Alemania) ofrece una buena referencia. La versión 2.1.0 exige JSON o XML en formato CycloneDX a partir de la versión 1.6 o SPDX a partir de la versión 3.0.1. Para cada componente exige, entre otros datos, el creador, el nombre, la versión, el nombre de archivo, la licencia, las dependencias y un valor hash SHA-512. Las dependencias se resuelven de forma recursiva, como mínimo hasta el primer componente que queda fuera de su volumen de entrega, incluido este.
¿CycloneDX o SPDX?
| CycloneDX | SPDX | |
|---|---|---|
| Origen | OWASP, normalizado como ECMA-424 | Linux Foundation, versión 2.2.1 como ISO/IEC 5962:2021 |
| Enfoque | seguridad y cadena de suministro, VEX posible en el mismo formato | originalmente licencias y cumplimiento normativo, desde la versión 3 también seguridad |
| Versión actual | 1.7 | 3.0.1 |
Ambos formatos cumplen el CRA. Lo decisivo es lo que procesan sus herramientas y sus clientes. Para la comparación con bases de datos de vulnerabilidades, por ejemplo con OWASP Dependency-Track, CycloneDX está muy extendido; las comprobaciones de licencias suelen trabajar tradicionalmente con SPDX. Es posible convertir entre ambos, pero no siempre sin pérdidas.
Generar la SBOM en la compilación
Si se mantiene a mano, una SBOM es errónea con la siguiente actualización de paquetes. Debe generarse en la compilación, y precisamente para la versión que se entrega. Para .NET existe la herramienta de línea de comandos CycloneDX; para Python, cyclonedx-py; para SPDX, por ejemplo, la sbom-tool de Microsoft:
# .NET: instalar la herramienta una vez y luego usarla en cada compilación de versión
dotnet tool install --global CycloneDX
dotnet-CycloneDX Produkt.sln -o sbom -fn produkt.cdx.json -F Json -t -sn Produkt -sv 2.4.0
# Python: a partir de requirements.txt
cyclonedx-py requirements requirements.txt --of JSON -o sbom/werkzeug.cdx.json
-sv establece la versión del producto y -t omite los proyectos de prueba. Después, un pequeño script comprueba si la lista de materiales está completa y hace fallar la compilación si faltan datos, por ejemplo licencias que la herramienta no pudo resolver:
import json
import sys
with open("sbom/produkt.cdx.json", encoding="utf-8") as datei:
komponenten = json.load(datei).get("components", [])
fehler = []
for komponente in komponenten:
name = komponente.get("name", "?")
for feld in ("version", "purl", "licenses", "hashes"):
if not komponente.get(feld):
fehler.append(f"{name}: {feld} fehlt")
print(f"{len(komponenten)} Komponenten geprüft, {len(fehler)} Lücken")
for zeile in fehler:
print(zeile)
sys.exit(1 if fehler else 0) # las lagunas hacen fallar la compilación
Lo que las herramientas no encuentran
Las herramientas leen los gestores de paquetes. Lo que llega al producto sin pasar por ellos falta: DLL copiadas, bibliotecas de C y C++, módulos comprados, firmware, entornos de ejecución incluidos y todo lo que el instalador coloca adicionalmente. Estos componentes se registran una vez en un archivo complementario que la compilación fusiona con la SBOM generada, por ejemplo con el comando merge de la CLI de CycloneDX. En los add-ins de CAD ocurre lo contrario: las DLL de AutoCAD o Revit contra las que compila no las entrega usted. No deben figurar como componente en su SBOM, pero sí como requisito previo en la documentación.
Y además la SBOM hay que utilizarla: archívela con cada versión junto con la documentación técnica y compárela continuamente con las bases de datos de vulnerabilidades; las nuevas vulnerabilidades afectan también a versiones que llevan tiempo funcionando en casa del cliente.
Nota: Este artículo ofrece una visión general técnica y no constituye asesoramiento jurídico.
Errores típicos
- Generar la SBOM a partir del código fuente en lugar de a partir de la compilación. Entonces no describe lo que realmente se entrega.
- Registrar solo los paquetes directos. Muchas vulnerabilidades están en dependencias transitivas.
- Una SBOM para todas las versiones. Cada versión entregada necesita la suya propia.
- Escribir las vulnerabilidades en la SBOM en lugar de en un documento VEX propio.
- Olvidar las DLL copiadas y las bibliotecas de C++, porque ningún gestor de paquetes las conoce.
Cómo le ayudamos
- SBOM en la compilación: configuramos la generación para .NET, C++ y Python, añadimos los componentes que faltan y comprobamos que esté completa, como parte de nuestros servicios en torno al Cyber Resilience Act.
- Vulnerabilidades: evaluamos las coincidencias para su producto y las corregimos: control de calidad y revisión de código.
- Primer paso: una jornada de asesoramiento a precio fijo aclara en qué punto se encuentran sus productos. O concierte una primera conversación.
Fuentes: Reglamento (UE) 2024/2847, art. 3, punto 39, art. 13, apdo. 24, anexo I, parte II, punto 1, anexo II, punto 9, anexo VII y considerando 77, EUR-Lex; BSI TR-03183-2, versión 2.1.0; CycloneDX; SPDX. Situación: octubre de 2026.
