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.
