{"id":1460,"date":"2026-07-08T12:22:20","date_gmt":"2026-07-08T12:22:20","guid":{"rendered":"https:\/\/cybercolombia.co\/index.php\/2026\/07\/08\/las-confirmaciones-verificadas-de-github-se-pueden-reescribir-en-nuevos-hashes-sin-romper-las-firmas-cyberdefensa-mx\/"},"modified":"2026-07-08T12:22:20","modified_gmt":"2026-07-08T12:22:20","slug":"las-confirmaciones-verificadas-de-github-se-pueden-reescribir-en-nuevos-hashes-sin-romper-las-firmas-cyberdefensa-mx","status":"publish","type":"post","link":"https:\/\/cybercolombia.co\/index.php\/2026\/07\/08\/las-confirmaciones-verificadas-de-github-se-pueden-reescribir-en-nuevos-hashes-sin-romper-las-firmas-cyberdefensa-mx\/","title":{"rendered":"Las confirmaciones &#8216;verificadas&#8217; de GitHub se pueden reescribir en nuevos hashes sin romper las firmas \u2013 CYBERDEFENSA.MX"},"content":{"rendered":"<div id=\"articlebody\">\n<p>Una nueva investigaci\u00f3n muestra que el hash de un compromiso Git firmado no es el nombre \u00fanico que gran parte del mundo del software supone que es. Dada cualquier confirmaci\u00f3n firmada, alguien sin la clave de firma puede crear una segunda confirmaci\u00f3n con los mismos archivos, autor y fecha, y una firma v\u00e1lida, GitHub a\u00fan marca \u00abVerificado\u00bb.<\/p>\n<p>Todo lo que un cr\u00edtico comprobar\u00eda coincide. El hash del compromiso no. Esto es importante porque muchos sistemas tratan un hash de confirmaci\u00f3n verificado como un nombre \u00fanico y permanente para su contenido.<\/p>\n<p>Aqu\u00ed est\u00e1 el fallo concreto: bloquear una confirmaci\u00f3n incorrecta mediante su hash, y un atacante puede volver a enviar el mismo contenido bajo un hash nuevo y a\u00fan \u00abverificado\u00bb que su lista de bloqueo nunca ha visto. La deduplicaci\u00f3n, los registros de procedencia y los registros de compilaci\u00f3n reproducible que codifican el hash heredan el mismo punto d\u00e9bil.<\/p>\n<p>Un espejo comprometido u hostil puede entregar a los clonadores confirmaciones firmadas v\u00e1lidamente cuyos hashes difieren de los de la forja can\u00f3nica.<\/p>\n<p>Lo que esto no es es una forma de pasar un c\u00f3digo diferente por una verificaci\u00f3n de firma. Los archivos son id\u00e9nticos en cada copia, por lo que un hash que fij\u00f3 a\u00fan obtiene exactamente el contenido que esperaba o falla.<\/p>\n<p>No hay CVE ni avisos de proveedores, y no hay nada que cambiar en su propio repositorio: la falla est\u00e1 en c\u00f3mo una falsificaci\u00f3n decide qu\u00e9 significa \u00abVerificado\u00bb, y la soluci\u00f3n pertenece al lado de la falsificaci\u00f3n.<\/p>\n<div class=\"dog_two clear\">\n<div class=\"cf\"><a href=\"https:\/\/thehackernews.uk\/ai-vuln-protection-d\" rel=\"nofollow noopener sponsored\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"lazyload\" alt=\"Ciberseguridad\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjQl2axNwsfhbXOFynrg_uAZsvHi3OvNGSA8KJO-BKR8Xm3x7yjKV3EvfY4v5mwXx6LF0uWFb9h9d9iAV_Pi-YYhqimX9wx4OaLdDJEdR215Xrxq_PAtXkaLfQso4pTSjbj6fvh_ZTliLpzWZSZfcoZgyXtKwhN-SSDDlmbtUqGLshc0KqYQGWYHMN52Sl1\/s728-e100\/zz-d.jpg\" width=\"729\" height=\"91\"\/><\/a><\/div>\n<\/div>\n<p>El trabajo proviene de <a href=\"https:\/\/arxiv.org\/abs\/2607.02820\" target=\"_blank\">Jacob Ginesin<\/a>estudiante de doctorado en la Universidad Carnegie Mellon y auditor criptogr\u00e1fico en Cure53. Su art\u00edculo de cinco p\u00e1ginas, publicado en arXiv el 2 de julio, viene con un <a href=\"https:\/\/github.com\/JakeGinesin\/git-chain-malleator\" target=\"_blank\">herramienta publica<\/a> que ejecuta los tres ataques, adem\u00e1s de dos repositorios de demostraci\u00f3n donde las confirmaciones maltratadas todav\u00eda muestran \u00abVerificado\u00bb en GitHub.<\/p>\n<p>Debido a que cada confirmaci\u00f3n nombra a su padre mediante hash, maltratar una confirmaci\u00f3n fuerza nuevos hashes en las confirmaciones que se encuentran encima de ella. La herramienta reescribe esa cadena para mantenerla consistente. Sin embargo, un descendiente firmado pierde su propia insignia en el momento en que cambia su puntero principal. Ginesin llama al efecto \u00ab<strong>maleabilidad de la cadena hash<\/strong>\u00ab.<\/p>\n<p>La causa es la maleabilidad caracter\u00edstica. El hash de una confirmaci\u00f3n se calcula sobre todo lo que contiene, incluidos los bytes sin procesar de la firma en su encabezado. Muchas firmas se pueden reescribir en una forma diferente pero a\u00fan v\u00e1lida, y cambiar esos bytes cambia el hash sin tocar una l\u00ednea de c\u00f3digo.<\/p>\n<p>Las tres rutas cubren todos los esquemas GPG que GitHub verifica, adem\u00e1s de S\/MIME:<\/p>\n<ul>\n<li><strong>Claves ECDSA:<\/strong> voltea la firma con una pieza cl\u00e1sica de \u00e1lgebra de curva el\u00edptica (convierte el valor s en n \u2013 s). Ambas formas son v\u00e1lidas. Esto pasa un compromiso de verificaci\u00f3n de git local y obtiene una insignia de GitHub.<\/li>\n<li><strong>Claves RSA y EdDSA:<\/strong> agregue un campo adicional ignorado a la secci\u00f3n \u00absin hash\u00bb de la firma, la parte que la firma deliberadamente no cubre. La firma a\u00fan se verifica, pero los bytes de la confirmaci\u00f3n y su hash cambian. Tanto Local como GitHub lo aceptan.<\/li>\n<li><strong>Teclas S\/MIME (X.509):<\/strong> reescriba un campo de longitud en la estructura DER de la firma en una forma m\u00e1s larga y no est\u00e1ndar. Una verificaci\u00f3n local estricta (a trav\u00e9s de gpgsm) lo rechaza, pero GitHub a\u00fan lo marca como \u00abVerificado\u00bb, y la herramienta reproduce ambas cosas.<\/li>\n<\/ul>\n<p>Las tres rutas comparten un habilitador: GitHub no normaliza una firma antes de verificarla. Sin codificaci\u00f3n estricta en S\/MIME, sin eliminaci\u00f3n de esos campos OpenPGP y los valores ECDSA no can\u00f3nicos se aceptan tal cual.<\/p>\n<p>Luego, GitHub archiva un registro \u00abVerificado\u00bb contra cada hash de confirmaci\u00f3n y no lo vuelve a verificar, por lo que una confirmaci\u00f3n permanece \u00abVerificada\u00bb incluso despu\u00e9s de que se revoca su clave de firma. Empuje un original y su gemelo a dos ramas, y la vista de comparaci\u00f3n de GitHub los tratar\u00e1 como historias divergentes, una confirmaci\u00f3n por delante y otra por detr\u00e1s, a pesar de archivos id\u00e9nticos.<\/p>\n<p>Para ser claros: esto no es una colisi\u00f3n de hash. No rompe SHA-1 o SHA-256, y no tiene nada que ver con el cambio de Git a SHA-256. Nadie obliga a dos confirmaciones diferentes a compartir un hash; es al rev\u00e9s, una confirmaci\u00f3n que se puede escribir de muchas maneras v\u00e1lidas, cada una con su propio hash.<\/p>\n<p>El movimiento central es antiguo. Bitcoin luch\u00f3 exactamente igual <a href=\"https:\/\/en.bitcoin.it\/wiki\/Transaction_malleability\" target=\"_blank\">simetr\u00eda ECDSA<\/a> Hace a\u00f1os, cuando cualquiera pod\u00eda invertir el valor s en la firma de una transacci\u00f3n y cambiar el ID de la transacci\u00f3n sin la clave del propietario. La soluci\u00f3n fue aceptar solo el formulario \u00ablow-S\u00bb y luego sacar las firmas del ID con SegWit.<\/p>\n<p>Las correcciones del art\u00edculo riman con eso: canonicalizar la codificaci\u00f3n antes de confiar en el hash. Una lecci\u00f3n conocida, no una criptograf\u00eda nueva y ex\u00f3tica.<\/p>\n<div class=\"dog_two clear\">\n<div class=\"cf\"><a href=\"https:\/\/thehackernews.uk\/sygnia-cyber-response-d-1\" rel=\"nofollow noopener sponsored\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"lazyload\" alt=\"Ciberseguridad\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEiqmM4NpfZsx4cw-HrXQlCjZQmrF8bYnmB23AmpOPi16kPNB9lvICjpdYEclxJwyQ9OE8GgzQ8aOEI68tRuxNqov0MHz2Sq8xEPiYWM3Js6FM5t2nm2JHWodmR7qVSot14ZtWVqQRQ6B88OnMaVxCPwRG7xGPoIIZxF6QAhWVhMkQfs11NjyNtHsGEUH4_q\/s728-e100\/sygnia-d-1.jpg\" width=\"729\" height=\"91\"\/><\/a><\/div>\n<\/div>\n<p>El documento tambi\u00e9n conecta esto con los recientes secuestros de etiquetas de GitHub Actions, los ataques tj-actions\/changed-files de 2025 y los ataques trivy-action de 2026 (cita este \u00faltimo). Despu\u00e9s de eso, el consejo fue simple: fijar un hash de confirmaci\u00f3n completo, no una etiqueta m\u00f3vil. Ese consejo sigue siendo v\u00e1lido.<\/p>\n<p>La fijaci\u00f3n detuvo esos ataques y esta investigaci\u00f3n no cambia eso. Su punto es m\u00e1s estrecho. En el caso Trivy, las confirmaciones maliciosas se destacaron porque no pod\u00edan firmarse v\u00e1lidamente. Esta es una advertencia contra confiar demasiado en esa indicaci\u00f3n: una firma v\u00e1lida prueba qui\u00e9n firm\u00f3 una confirmaci\u00f3n, pero no hace que el hash de la confirmaci\u00f3n sea un nombre \u00fanico para lo que contiene.<\/p>\n<p>Entonces \u00bfqui\u00e9n tiene que hacer algo? No el desarrollador que fija una acci\u00f3n o un m\u00f3dulo; un hash fijado a\u00fan obtiene el c\u00f3digo correcto. El trabajo es para las fraguas. El peri\u00f3dico dice que deber\u00edan canonicalizar las firmas antes de confiar en ellas.<\/p>\n<p>Las herramientas que bloquean, deduplican o registran la procedencia mediante hash de confirmaci\u00f3n deber\u00edan hacer lo mismo, verificando y canonicalizando primero en lugar de confiar en el hash sin formato de un objeto firmado que un atacante puede volver a codificar. No todos los sistemas est\u00e1n igualmente expuestos: los esquemas que tambi\u00e9n fijan un hash independiente de los archivos recuperados, como las derivaciones de salida fija de Nix, mantienen un respaldo; aquellos que se detienen en un hash de confirmaci\u00f3n verificado no lo hacen.<\/p>\n<p>Ginesin dice que inform\u00f3 del problema a GNU y Git en enero y a GitHub en marzo, y que hasta la publicaci\u00f3n del art\u00edculo, ni Git ni ninguna falsificaci\u00f3n lo hab\u00edan abordado. La soluci\u00f3n del lado de la falsificaci\u00f3n se comprende bien, y el lugar obvio para comenzar es el caso S\/MIME, donde GitHub todav\u00eda acepta lo que una estricta verificaci\u00f3n local rechaza.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Una nueva investigaci\u00f3n muestra que el hash de un compromiso Git firmado no es el nombre \u00fanico que gran parte del mundo del software supone que es. Dada cualquier confirmaci\u00f3n firmada, alguien sin la clave de firma puede crear una segunda confirmaci\u00f3n con los mismos archivos, autor y fecha, y una firma v\u00e1lida, GitHub a\u00fan [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1379,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25,5],"tags":[603,24,3599,931,2870,95,1262,900,3597,3598,716,1102],"class_list":["post-1460","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-noticias","category-trending","tag-confirmaciones","tag-cyberdefensa-mx","tag-firmas","tag-github","tag-hashes","tag-las","tag-nuevos","tag-pueden","tag-reescribir","tag-romper","tag-sin","tag-verificadas"],"_links":{"self":[{"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/posts\/1460","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/comments?post=1460"}],"version-history":[{"count":0,"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/posts\/1460\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/media\/1379"}],"wp:attachment":[{"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/media?parent=1460"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/categories?post=1460"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cybercolombia.co\/index.php\/wp-json\/wp\/v2\/tags?post=1460"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}