
Laboratorio aislado de regresión y control de seguridad para CVE-2026-59891 en @sigstore/oci
Proyecto de laboratorio aislado y auditoría de solo lectura que compara las versiones vulnerable y corregida reales de @sigstore/oci con la misma entrada y comprueba las condiciones de exposición según el entorno.
El CVE Reporter de este proyecto es gyubin02.
Resumen para contratación y entrevistas: Caso de automatización de gestión de vulnerabilidades CVE-2026-59891
El núcleo de CVE-2026-59891 es la confusión de hostname que se produce al elegir las credenciales del Registry.
0.7.0: puede seleccionar las credenciales de ghcr.io porque cr.io está contenido en la cadena ghcr.io.0.7.1: tras normalizar el hostname, solo selecciona las credenciales que coinciden exactamente.Este repositorio verifica automáticamente dos escenarios de selección de credenciales.
ghcr.io, pero el destino es cr.iocr.io que coinciden exactamente con el destinoLa versión vulnerable debe seleccionar incorrectamente las credenciales en el primer escenario, y la versión corregida debe rechazarlas. Ambas versiones deben superar el segundo escenario normal.
Además, se ha añadido una comparación dinámica que utiliza un mock Registry desechable en 127.0.0.1 en lugar de un Registry externo real. La versión vulnerable 0.7.0 realiza 2 solicitudes locales y, tras el challenge de autenticación, se observa un header Authorization sintético en la segunda solicitud. La versión corregida 0.7.1 es rechazada en la fase de selección de credenciales, por lo que realiza 0 solicitudes. En los resultados solo quedan la observación (sí/no) y el número de solicitudes, no el valor del header.
cve-2026-59891-audit lee únicamente los metadatos del package-lock.json del proyecto objetivo y del Docker config especificado explícitamente, y distingue lo siguiente:
@sigstore/ociEjecución inmediata con un fixture sintético:
npm run audit:demo
Verificación de otro proyecto Node.js:
npm run audit:project -- \
--project ../target-project \
--docker-config ../review-copy/config.json \
--image cr.io/example/demo \
--destination-trust unknown \
--format markdown \
--output reports/cve-2026-59891.md
--destination-trust debe especificar obligatoriamente uno de los siguientes valores:
trusted: confirma que el destination está restringido mediante código y allowlistuntrusted: entradas externas o entradas del workflow afectan al destinationunknown: aún no se ha podido confirmarEl veredicto se divide en exposure_conditions_met, potential_exposure, affected_component_only, not_detected e indeterminate. not_detected es solo el resultado para el alcance de entradas registrado; no significa «seguro» ni «cumplimiento normativo».
~/.docker/config.json real.HOME dedicado y aislado y valores ficticios sin valor: lab-user / LAB_ONLY_FAKE_TOKEN.HOME, el marcador del laboratorio y los valores ficticios son todos correctos.fetch.127.0.0.1 asignado por el SO. Se bloquean el HTTP externo o hacia otros puertos, el resolver DNS, TLS, UDP, el fetch global y WebSocket.--docker-config y no infiere archivos desde HOME ni DOCKER_CONFIG.Dado que se instala intencionadamente el paquete vulnerable, la distribución del paquete npm está bloqueada con "private": true. No debe utilizarse como dependencia de código de producción.
Por ello, que npm audit reporte 0.7.0 es un resultado esperado; el alcance y el motivo de la excepción están documentados en SECURITY.md.
Requisitos: Node.js 22.22.2+, 24.15.0+ o 26 o superior. La versión recomendada está fijada en .nvmrc.
npm ci --ignore-scripts
npm test
npm run demo
npm run dynamic:demo
npm run audit:fixture
npm run audit:demo
npm run evidence
Resultados esperados clave de npm run demo:
0.7.0 collision credential-selected
0.7.1 collision credential-rejected
0.7.0 exact credential-selected
0.7.1 exact credential-selected
Regression result: PASS
Resultados esperados clave de npm run dynamic:demo:
{
"vulnerable": {
"packageVersion": "0.7.0",
"credentialSelection": "credential-selected",
"requestCount": 2,
"authorizationObserved": true,
"digestVerified": true,
"networkPolicy": "exact-loopback-only"
},
"fixed": {
"packageVersion": "0.7.1",
"credentialSelection": "credential-rejected",
"requestCount": 0,
"authorizationObserved": false,
"digestVerified": false,
"networkPolicy": "exact-loopback-only"
},
"regressionResult": "PASS"
}
Hay 34 pruebas automatizadas en total. npm run evidence genera 7 archivos en total: los 6 artefactos sujetos a inspección más SHA256SUMS, que verifica su integridad.
Este proyecto es una evaluación controlada y limitada con fines educativos. Los resultados loopback solo demuestran diferencias de comportamiento en un entorno sintético; no demuestran la exposición o el compromiso de credenciales ni la eficacia de los controles en un entorno empresarial real. No implica la certificación CISA, la certificación ISMS-P ni el cumplimiento normativo de ninguna organización específica. El Node API guard es una capa de defensa para las rutas de ejecución observadas de las dependencias bloqueadas, no un namespace de red ni un firewall a nivel de SO.
La documentación detallada del alcance, las pruebas, los riesgos y los controles está en docs/, y npm run evidence genera un registro de ejecución reproducible y un manifest SHA-256.
npm-shrinkwrap.json de mayor prioridad, falla sin afirmar que sea seguro.