Tornar al Blog

Clonar el repositori no és tenir còpia de GitLab

Clonar el repositori no és tenir còpia de GitLab

El 17 d'agost GitLab va publicar quatre versions fora de calendari. La fallada que les motiva permet, sota certes condicions i sense necessitat de compte, modificar o esborrar projectes públics. Quan ho expliques, la resposta gairebé sempre és la mateixa: «el codi el tenim clonat a tots els portàtils». És veritat. I és la part que menys es perd.

Quatre versions un dilluns a la tarda

GitLab va publicar el 17 d'agost del 2026 les versions 19.2.4, 19.1.6, 19.0.8 i 18.11.11 com a pedaç crític, fora del cicle normal d'actualitzacions de seguretat. Mana CVE-2026-19478, titulada «Code Injection issue via GraphQL directive impacts GitLab CE/EE», crítica, 9,4 de CVSS, amb vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:H. La descripció del fabricant, sencera: «GitLab has remediated an issue that under certain conditions could allow an unauthenticated user to remotely modify or delete public projects and user data via a GraphQL directive». La va reportar hiimguardian a través de HackerOne.

Afecta CE i EE des de la 18.2 fins abans de la 18.11.11, des de la 19.0 fins abans de la 19.0.8, des de la 19.1 fins abans de la 19.1.6 i des de la 19.2 fins abans de la 19.2.4. Al mateix lot hi va CVE-2026-19650 (alta, 7,1), un CSRF al gestor de consultes múltiples de GraphQL que «under certain conditions could have allowed an unauthenticated user to execute mutations via GET requests due to improper request validation». Aquest segon necessita que algú amb sessió oberta hi piqui —el seu vector porta UI:R—, cosa que el primer no.

Dues coses que convé dir encara que desinflin l'assumpte. A 17 i 18 d'agost no consta explotació activa ni codi d'exploit públic; qui vengui urgència amb l'expressió «activament explotat» aquí, se l'està inventant. I «under certain conditions» és a la frase original: GitLab no diu quines i nosaltres no omplirem el buit. El que sí que és ferm és a qui li toca treballar. GitLab.com i GitLab Dedicated ja corrien la versió pedaçada; per a les instàncies autoallotjades la instrucció és actualitzar «immediately».

El que un clon no s'emporta

El titular diu «esborrar projectes» i el cap va al codi. I el codi és, de tot el que hi ha dins d'un GitLab, l'única cosa replicada per disseny: cada portàtil de l'equip té l'arbre i la història.

Amb una excepció que se li escapa a gairebé tothom: els runners no. GitLab CI clona en superfície per defecte, amb profunditat 20. El que hi ha a la màquina que construeix la teva imatge són vint commits.

És a qualsevol clon Viu només al servidor
Commits, branques i etiquetes Issues i la seva discussió
La història completa de l'arbre Merge requests, revisions i aprovacions
El .gitmodules i el punter del submòdul Variables de CI/CD i els seus valors
  Registre de contenidors i de paquets
  Artefactes i logs dels jobs
  Wikis (repositori git a part)
  Notes de git (refs/notes, no es clonen soles)
  Protecció de branques, entorns, webhooks
  Membres, permisos, tokens i runners registrats

Dues files d'aquesta taula mereixen una nota. Les wikis són repositoris git independents: ningú no clona a mà projecte.wiki.git, de manera que la documentació que l'equip va escriure al costat del codi és al servidor i enlloc més. I el submòdul: el teu clon guarda un punter de quaranta caràcters, no el contingut, i el repositori al qual apunta pot ser un altre dels que s'acaben d'esborrar.

El dany d'un esborrat no es mesura en repositoris. Es mesura en per què es va decidir allò, qui ho va aprovar, amb quina variable es desplega a producció i quina imatge exacta està corrent ara mateix. Res d'això no és a cap portàtil.

Al juny n'hi va haver un altre, i no portava CVE

Aquest és el precedent que gairebé cap cobertura de la fallada d'agost no esmenta, i és el que millor explica el problema de fons. Al juny, en Yuhang Wu, de depthfirst, va encadenar dues fallades de corrupció de memòria de l'analitzador JSON Oj de Ruby a través del renderitzat de diffs de quaderns Jupyter, i va aconseguir executar ordres en instàncies autoallotjades. No calia ser administrador: qualsevol usuari autenticat que pogués fer push a un projecte. Afectava de la 15.2.0 a la 18.10.7, de la 18.11.0 a la 18.11.4 i de la 19.0.0 a la 19.0.1. Es va corregir el 10 de juny del 2026 a 18.10.8, 18.11.5 i 19.0.2, i la prova de concepte es va publicar el 24 de juliol.

Sense cap CVE. I aquí hi ha un detall que és fàcil d'explicar malament, així que ho diem sencer: segons The Hacker News, el mateix investigador va afirmar que depthfirst no va demanar identificadors CVE per a cap de les dues fallades, i GitLab no va contestar les preguntes d'aquell mitjà sobre per què l'arranjament no es va classificar com a problema de seguretat. No cal suposar mala fe de ningú per arribar a la conclusió incòmoda.

La conclusió és que si el teu procés de pedaços es dispara amb els butlletins de CVE, aquell arranjament va passar per davant sense encendre cap llum. Una instància que es va quedar a la branca 19.0 sense arribar a la 19.0.2 va acumular, entre juny i agost, un camí a execució d'ordres amb un compte qualsevol i un esborrat de projectes sense compte. Cap de les dues coses no l'hauria avisat un lector de CVE. Sí que l'avisa saber en quina versió ets i comparar-la amb l'última, que és una feina molt més avorrida. És la mateixa disciplina que ja vam explicar parlant dels nostres desplegaments: una etiqueta no és una versió.

La clau no és on és la còpia

Suposem que passa. gitlab-backup create fa més del que la gent es pensa: base de dades i la seva configuració, repositoris i objectes LFS, artefactes i logs dels jobs, ajustos de comptes i grups, registre de paquets i imatges del registre de contenidors, wikis de projecte i de grup, adjunts i pujades, i algunes que sorprenen, com els estats de Terraform, el contingut de Pages i els snippets.

I no inclou els fitxers de configuració de GitLab (/etc/gitlab, amb gitlab.rb i gitlab-secrets.json), ni les claus i certificats TLS i SSH, ni Redis —i amb ell la cua de treballs de Sidekiq—, ni els hooks globals de servidor i de fitxer, ni l'emmagatzematge d'objectes en instal·lacions estàndard per paquet, Docker o compilades. Aquest últim mereix un avís a part: si els teus artefactes, pujades, paquets i objectes LFS viuen en un bucket, la teva còpia de GitLab no els porta a dins.

El que fa mal és gitlab-secrets.json, i convé entendre per què amb precisió. No és que aquell fitxer contingui les teves variables de CI/CD: les variables estan xifrades a la base de dades, que sí que va dins de la còpia. El que conté el fitxer és la clau amb què es desxifren. La documentació ho raona amb una frase que hauria d'estar penjada a més despatxos: desar la informació xifrada al mateix lloc que la seva clau anul·la el propòsit de xifrar-la. I descriu la conseqüència de perdre-la sense adorns: «Without the keys, multiple issues occur, including loss of access by users with two-factor authentication enabled, and GitLab Runners cannot sign in».

Un dimarts al matí això es veu així: restaures, la base de dades entra sencera, els repositoris hi són, la interfície arrenca, i les variables de desplegament són il·legibles, els runners no poden iniciar sessió i la gent amb segon factor es queda fora. És cosí germà d'una dependència sobre la qual ja vam escriure: el servidor de còpies que depèn d'allò de què et protegeix.

Queda l'altre requisit, a la mateixa documentació: «You can only restore a backup to exactly the same version and type (CE or EE) of GitLab on which it was created». La mateixa versió i la mateixa edició. D'aquí surt un ordre d'operacions que convé tenir escrit abans i no descobert durant:

  1. Instal·lar la versió exacta —i l'edició exacta— amb què es va fer la còpia.
  2. Posar al seu lloc els secrets i la configuració.
  3. Restaurar la còpia.
  4. I llavors actualitzar a la versió pedaçada.

El pas u és incòmode de llegir: si el desastre t'enxampa desactualitzat, la ruta de tornada passa per aixecar un altre cop la versió vulnerable. No és motiu per no restaurar. Sí que ho és perquè aquella màquina no estigui publicada a Internet mentre dura la feina, i perquè el pas quatre sigui al mateix document que el pas u. Abans de tot això hi ha una pregunta més ximple i més urgent: quina versió exacta tenies ahir a la nit? Si no està escrita al costat del fitxer de la còpia, la restauració comença amb arqueologia.

Què faríem aquesta setmana

  • Mirar la versió. A la interfície, /help. En instal·lació per paquet, sudo gitlab-rake gitlab:env:info. Anotar-la —amb l'edició, CE o EE— on es guarda la còpia, no al cap de ningú.
  • Actualitzar a 19.2.4, 19.1.6, 19.0.8 o 18.11.11, segons la branca.
  • Comptar els projectes públics de debò, no els que un recorda. Si hi apareix res que no esperaves, aquesta és la troballa del dia, amb pedaç o sense.
# Compta per pàgines: 100 a la primera pàgina vol dir que n'hi ha més
for p in $(seq 1 20); do
  n=$(curl -s "https://TU-GITLAB/api/v4/projects?visibility=public&simple=true&per_page=100&page=$p" | jq 'length')
  echo "page $p: $n"; [ "$n" -lt 100 ] && break
done
  • Decidir què s'ha de veure des d'Internet: la instància sencera, el llistat públic de projectes, cap de les dues. El desembre del 2024 Cycode va localitzar amb Shodan més de 40.000 servidors GitLab autoallotjats; el número té any i mig i el costum continua igual.
  • Treure els secrets de la màquina. gitlab-secrets.json i gitlab.rb fora, xifrats, amb la mateixa disciplina que la còpia gran. Al mateix disc que GitLab no són una còpia.
  • Assajar la restauració en una màquina neta fins a veure un pipeline en verd. No fins que arrenqui la interfície: fins que un job real acabi bé i un runner hagi pogut iniciar sessió.
  • Mirar on és l'emmagatzematge d'objectes. Si és fora, es copia a part i s'escriu al mateix document, perquè el dia dolent ningú no se'n recorda.

El que no recomanarem

Anar-se'n al servei gestionat per això. GitLab.com estava pedaçat abans que ningú se n'assabentés, i com a argument és honest i cal reconèixer-ho. Però mudar una plataforma sencera per no haver d'aplicar pedaços és canviar una feina que coneixes per una altra que encara no; i les raons per les quals algú s'autoallotja —on viu el codi, amb què s'integra, què costa— no les deroga un butlletí de seguretat.

Ficar-lo sencer darrere la VPN sense mirar. És la reacció reflexa i de vegades és la correcta, però trenca coses que algú està fent servir ara mateix: webhooks entrants, runners externs, integracions de tercers, pàgines publicades. Si es fa, es fa amb la llista del que es trenca al davant i avisant qui la faci servir, que és més feina que teclejar una regla de tallafocs. És la mateixa cadena de detalls petits de què parlàvem en repassar com s'esmuny un secret en un pipeline.

I toca declarar el conflicte d'interès, perquè aquí no parlem des de la grada: fem servir GitLab autoallotjat per al nostre propi CI/CD i per desplegar aquesta mateixa web. La llista de dalt ens l'apliquem nosaltres, amb el mateix calendari i les mateixes presses.

Dues preguntes que no cal contestar en públic

L'eina amb què es desplega tota la resta és, a gairebé totes les empreses que coneixem, l'única que no té finestra de manteniment pròpia, ni pla de restauració escrit, ni assaig. S'actualitza quan no molesta, que és mai, perquè sempre hi ha algú desplegant.

Així doncs, dues preguntes, i no cal contestar-les en veu alta: quant triga el teu equip a pedaçar l'eina amb què desplega la resta? I, sense anar a mirar-ho: quina versió exacta caldria instal·lar per poder restaurar la còpia d'ahir a la nit?

Fonts (verificades el 19 d'agost del 2026): les versions publicades el 17 d'agost del 2026, els identificadors CVE-2026-19478 i CVE-2026-19650, els seus títols, gravetats, puntuacions i vectors CVSS, les descripcions citades literalment, els rangs de versions afectades, els reporters hiimguardian i kreep, la recomanació d'actualitzar «immediately» i que GitLab.com i GitLab Dedicated ja corrien la versió pedaçada, de GitLab Docs, «GitLab Critical Patch Release: 19.2.4, 19.1.6, 19.0.8, 18.11.11». L'absència d'explotació coneguda i d'exploit públic a 17-18 d'agost, de la cobertura de The Hacker News. Què inclou i què no inclou l'arxiu de còpia, de «Back up GitLab»; el requisit de restaurar sobre la mateixa versió i edició i la frase sobre les claus, de «Restore GitLab». La cadena de juny (Yuhang Wu / depthfirst, analitzador Oj i diffs de quaderns Jupyter), les versions afectades i corregides el 10 de juny del 2026, la publicació de la prova de concepte el 24 de juliol, que depthfirst no va demanar identificadors CVE i que GitLab no va respondre les preguntes sobre la classificació de l'arranjament, de The Hacker News. Els més de 40.000 servidors GitLab autoallotjats localitzats amb Shodan, de Cycode Labs, publicat el 15 de desembre del 2024 i citat amb la seva data. La profunditat de clonatge per defecte de GitLab CI (20) i que les wikis són repositoris git independents, de la documentació de GitLab. Són nostres: la lectura que el que es perd en un esborrat és el context i no el codi, la taula de què és en un clon i què no, l'ordre d'operacions de la restauració, la tesi que pedaçar seguint butlletins de CVE deixa fora arranjaments sense CVE, la llista de comprovacions i les dues posicions del «que no recomanarem». Les cites de GitLab es deixen en anglès, el seu idioma original, perquè es puguin verificar paraula per paraula.

Quan es va provar per última vegada aquella restauració?

Als plans de disaster recovery que escrivim, l'assaig de restauració va amb data i amb resultat, no amb bona voluntat. I quan ens fem càrrec de la infraestructura i el cloud d'algú, l'inventari de versions és de les primeres coses que posem per escrit, perquè és el que decideix quant dura un mal dia.

Parlar amb everyWAN

Etiquetes:

Compartir:

Subscriu-te al nostre butlletí

Per rebre històries del món IT, novetats d'everyWAN i ofertes exclusives per a subscriptors, dona't d'alta a la nostra llista de correu

everyWAN
everyWAN