News

El verificador de commits de Core aceptaba historiales ajenos

Dos caminos del script que comprueba el historial firmado de Bitcoin Core llegaban a la salida correcta sin demostrar nada: un comando de git que fallaba y un historial divergente del root de confianza. El arreglo obliga al script a probar el vínculo o negarse.

4 min de lecturaBitcoin Core
El verificador de commits de Core aceptaba historiales ajenos

Qué pasó

El 19 de agosto de 2026 Bitcoin Core integró el pull request 35980, un cambio de dos commits sobre contrib/verify-commits/verify-commits.py. Ese script recorre el historial de commits del repositorio y comprueba que cada commit, hasta un root de confianza configurado, fue firmado por una clave de una lista de confianza. Dos caminos distintos llegaban a la misma salida correcta sin establecer nada. El pull request describe el problema con sus propias palabras: "un commit que es antecesor de un root configurado se acepta de forma intencionada sin comprobar el historial anterior. El script también toma este camino de éxito tras errores de Git o ante commits divergentes, aunque ninguno de los dos establece esa relación". Y añade que el problema "también fue encontrado y divulgado de forma responsable por el Red Team".

Qué cambia

El script responde una sola pregunta antes de que alguien compile nada: el historial que está en esta copia local, ¿es el historial que firmaron quienes mantienen el proyecto? Las firmas lo responden commit a commit, y una prueba de ancestría decide dónde parar, porque los commits anteriores al root de confianza quedan deliberadamente fuera de alcance.

La regla de parada era el agujero. El código anterior le preguntaba a git si el root de confianza era antecesor del commit examinado, y leía cualquier salida distinta de cero como "este commit es anterior al root, se para aquí", imprimía un mensaje y terminaba con éxito. Git devuelve 1 para "no es antecesor", lo que cubre tanto a un commit genuinamente anterior al root como a un commit de un historial que no comparte ninguna ancestría con él. Otros códigos de salida significan que git no pudo responder: un objeto ausente, un repositorio roto. Esos casos tomaban la misma rama.

El cambio encauza ambas preguntas por dos funciones auxiliares del script actual. is_ancestor ahora trata cualquier código de salida de git distinto de 0 o 1 como fatal y se detiene, nombrando los dos commits que no pudo comparar. predates hace la pregunta en ambas direcciones y devuelve verdadero solo cuando el commit es demostrablemente antecesor del root, tal como dice su docstring: "Devuelve si el commit es demostrablemente anterior al root, rechazando historiales divergentes". Cuando ninguna dirección se cumple, informa de que el commit "diverge del root de confianza de Git" y termina con error. Una herramienta de verificación que termina con éxito cuando no pudo hacer la verificación es peor que no tener herramienta, porque le entrega a una persona un resultado en el que apoyarse. Ambos casos vienen con reproductores.

Qué no cambia

Esto es una comprobación sobre una copia local, que ejecuta quien decide ejecutarla. El README de la propia herramienta es explícito sobre el orden: descargar, verificar con una copia confiable del script y solo después hacer checkout, porque "no se puede usar un script no confiable para verificarse a sí mismo". Nada de eso cambió, y quien nunca ejecuta el script no gana nada con que sea mejor. Tampoco es lo que comprueba alguien que descarga una publicación: ese es otro artefacto, con su propia firma.

Nada de esto dice que el fallo se haya usado. El pull request aporta reproductores, que demuestran que el script aceptaba lo que debía rechazar. Mostrar que una cerradura se puede forzar no es prueba de que alguien haya entrado en la casa.

Y una ejecución que pasa sigue significando solo lo que siempre significó: estos commits llevan firmas de claves que están en la lista de confianza de este repositorio. Si esas claves pertenecen a las personas que uno cree, esa es la pregunta de cadena de suministro que hay debajo, y queda fuera del script, como quedó siempre.

Contexto

Core lleva años haciendo que sus propios modos de fallo sean legibles en lugar de silenciosos. Empezó a publicar las vulnerabilidades corregidas en julio de 2024, con el razonamiento de que a nadie se le puede obligar a actualizar, así que el silencio solo deja adivinando a quienes operan un nodo. El repositorio de BIPs añadió una vía para reportar un fallo en una especificación a principios de este mes. Este arreglo apunta el mismo instinto a las herramientas: lo que elimina no es una respuesta equivocada, sino una respuesta segura de sí misma.

La mención al Red Team en la descripción es el único rastro de cómo llegó el reporte. El pull request no dice quiénes son ni qué más revisaron, y el repositorio no guarda más registro del asunto.

Boletín

Bitcoin, sin ruido

Qué ha pasado en Bitcoin, qué cambia de verdad, y las fuentes para que puedas comprobarnos. Un número cada vez, directo a tu correo.

  • Un correo por número, nunca una secuencia automática
  • Sin píxeles de seguimiento y sin compartir direcciones
  • Baja desde cualquier número con un clic

Recibe el próximo número

Un correo por número, sin píxeles de seguimiento, y te puedes dar de baja desde cualquiera de ellos. No compartimos tu dirección. Política de privacidad