Tornar al Blog

El clone no porta el .git/config. El ZIP sí

El clone no porta el .git/config. El ZIP sí

Un proveïdor t'envia un ZIP amb el projecte. El descomprimeixes i obres la carpeta amb el teu agent d'IA per fer-hi un cop d'ull. Segons quin sigui l'agent, ja no cal res més: ni aprovar una ordre, ni que es cridi cap model, ni que ningú no et pregunti si confies en aquella carpeta. I un programa que ha triat una altra persona s'està executant amb els teus permisos.

Això no és una hipòtesi de laboratori: és la descripció textual de quatre CVE publicats entre el 10 d'agost i el 3 de setembre del 2026 contra productes de tres fabricants diferents. I la part interessant no és la fallada —que s'arregla— sinó la via de lliurament, perquè és l'única part que no depèn de cap fabricant i la que gairebé tothom està llegint al revés.

Qui executa el programa no és l'agent: és git

La peça central es diu core.fsmonitor i no és una vulnerabilitat de git: és una opció documentada que fa exactament el que diu. La documentació oficial, després d'explicar el monitor integrat, remata amb una frase que convé llegir a poc a poc: «Otherwise, this variable contains the pathname of the "fsmonitor" hook command». És a dir, el valor d'aquella variable és la ruta d'un programa, i git l'executa per estalviar-se recórrer l'arbre de fitxers: «This hook command is used to identify all files that may have changed since the requested date/time».

Aquest ajust viu al .git/config del mateix repositori. I git status o git diff refresquen l'índex, de manera que l'invoquen. Un agent d'IA, en obrir una carpeta, fa justament això: crida git per saber en quina branca és, quins fitxers hi ha tocats i quin context posar-li al model. Aquí s'acaba la cadena. No cal cap astúcia més.

Els quatre expedients, amb els seus números

CVE Producte CVSS Clau abusada Què cal
CVE-2026-19592Codex CLI / Desktop7,3 (v3.1)core.fsmonitorObrir o fer servir el repo
CVE-2026-19593Codex Desktop9,8 (v3.1)attr.tree + filtreObrir l'espai de treball
CVE-2026-72718goose (Block)7,0 (v4.0)core.fsmonitorgoose review
CVE-2026-71963Hermes Agent8,8 (v3.1)core.fsmonitorEnviar un missatge

L'última columna és la que convé no saltar-se, perquè la premsa l'ha aplanada: no són quatre «obres la carpeta i ja». Els dos de Codex sí: n'hi ha prou amb obrir l'espai de treball. A goose cal llançar goose review, i a Hermes cal enviar un missatge qualsevol. El que comparteixen tots quatre no és que no facis res, és què és el que passa abans que ningú no pregunti res.

El de goose és el que dona més detall, fins al punt d'anomenar el fitxer font: les crides vulnerables les construeix git_command() a crates/goose-cli/src/commands/review/handler.rs, i les fan servir touched_files() i collect_diff(). Corregit a la 1.44.0. La frase que importa del seu registre és quan passa: «The command runs before goose contacts a model and without a submitted prompt, model call, tool approval, or trust prompt». En el d'Hermes Agent (versions 0.18.2 a 0.21.0, corregit al commit f6234d0) el resultat es descriu sense eufemismes: l'ordre injectada s'executa en el context del procés de l'usuari «exposing the full environment including configured provider API keys».

La variant que no es veu a la teva carpeta

El CVE de 9,8 mereix paràgraf a part perquè no fa servir fsmonitor i és el més incòmode d'auditar. Fa servir attr.tree, una altra opció perfectament documentada: «A reference to a tree in the repository from which to read attributes, instead of the .gitattributes file in the working tree». Llegeix-ho un altre cop: els atributs no es llegeixen del .gitattributes que tu veus en obrir la carpeta, sinó d'un objecte tree desat dins del repositori. Combina-ho amb un filtre clean o process declarat al .git/config i ja tens un programa que git executa en refrescar l'índex.

L'incòmode d'auditar-ho és això: la regla que assigna el filtre al fitxer no és a cap lloc on un revisor humà miri en rebre un projecte. Però del 9,8 convé dir d'on surt, perquè l'expedient té truc. Les puntuacions dels dos CVE de Codex no les posa OpenAI: són mètriques secundàries aportades pel programa ADP de CISA. I el vector que li assignen, AV:N/AC:L/PR:N/UI:N, diu que no cal interacció de l'usuari, quan la descripció del mateix CVE exigeix que l'usuari obri el repositori preparat. Nosaltres ens quedem amb la descripció, que és la que signa qui va investigar, i allà els requisits són dos: «Exploitation requires Git to be available on PATH and the user to open the attacker-prepared repository with its local Git configuration intact». El primer és banal. El segon és tot aquest post.

Per eliminació: el clone no és la via

La reacció natural en llegir això és «doncs ja no clono repositoris estranys». I és justament la conclusió equivocada, perquè el git clone és l'únic camí que no funciona. Ho diu el mateix registre del CVE, sense deixar espai a interpretació: «An ordinary Git clone does not preserve the source repository's local .git/config; exploitation requires a repository delivered or copied with that configuration intact».

Clonar és un protocol: el servidor envia objectes i referències, i el teu git escriu un .git/config nou. Copiar és una altra cosa: copiar mou bytes, i entre aquests bytes hi va el .git sencer. Així que la pregunta no és per on clones, sinó per on t'arriben carpetes. La nota de la Cloud Security Alliance enumera les vies que sí que funcionen —«a .zip archive, a folder on a shared network drive, a synced cloud-storage folder, or a USB stick»— i el que ens interessa d'aquella llista és que no descriu quatre escenaris exòtics: descriu quatre coses que la teva empresa ja té muntades i pagades.

  • ·El ZIP adjunt al correu del client o del proveïdor. La teva passarel·la mira macros i executables; una carpeta oculta amb fitxers de text li sembla un projecte.
  • ·La carpeta del recurs compartit, el NAS on es deixa «això del projecte de tal» i on escriu mitja empresa.
  • ·La carpeta sincronitzada d'emmagatzematge al núvol, que a sobre replica el .git a tots els qui la comparteixen.
  • ·El llapis USB i el contenidor de desenvolupament prefabricat que algú es va baixar perquè «ja porta l'entorn muntat».

Cap d'aquestes quatre portes mira dins d'un .git/config. Ja vam escriure sobre l'altre extrem del mateix problema quan van aparèixer milers de repositoris falsos encebats perquè els recomanés un agent; allò anava de què et baixes. Això va de què et deixen damunt la taula.

Git sí que té una comprovació. I aquestes quatre vies la desarmen

Aquí hi ha, per a nosaltres, el més interessant de tot l'assumpte, i no apareix ni a la nota de la Cloud Security Alliance ni a la divulgació original. Git no és ingenu amb això. Des de l'embolic de safe.directory porta una defensa dura i la seva documentació la descriu així: «By default, Git will refuse to even parse a Git config of a repository owned by someone else, let alone run its hooks». Ni tan sols llegeix la configuració. És exactament la protecció que caldria.

Ara torna a mirar com arriba la carpeta. En el camí normal —descomprimeixes el ZIP, et copies del recurs compartit al teu disc, el client de sincronització l'escriu— l'últim que escriu els fitxers ets tu, i surten al teu nom. La comprovació passa sense despentinar-se. Perquè aquella defensa està dissenyada contra el repositori d'un altre al teu disc, i el que tens al davant és la teva còpia del repositori d'un altre. Són coses diferents i es comporten igual de malament.

El matís, perquè el té i no el volem vendre més rodó del que és: no val per a tots els casos. Si obres el repositori al lloc, sobre un recurs de xarxa que conserva l'identificador d'usuari de qui el va deixar allà, git sí que salta amb el seu avís de propietat dubtosa i es nega a llegir la configuració. El mateix si algú va muntar el llapis USB com a root sense reassignar propietari. El problema és que cap d'aquests dos no és el gest habitual: el gest habitual és endur-se'l al meu disc i obrir-lo, i aquest és justament el que desactiva la defensa.

I hi ha un segon detall a la mateixa documentació que tanca el raonament. Git té un concepte anomenat configuració protegida, pensat exactament per a això: «Protected configuration refers to the system, global, and command scopes. For security reasons, certain options are only respected when they are specified in protected configuration, and ignored otherwise». Hi ha opcions que un repositori simplement no pot fixar. safe.bareRepository n'és una, i la documentació ho justifica amb totes les lletres: «This prevents untrusted repositories from tampering with this value». Quantes opcions hi ha en aquell club? Ho hem comptat: dels 97 fitxers de Documentation/config/ de la branca principal de git, només tres opcions es documenten com a respectades únicament en configuració protegida —safe.directory, safe.bareRepository i uploadpack.packObjectsHook—. Tres, en tot git. core.fsmonitor, una opció el valor documentat de la qual és la ruta d'un programa, no n'és cap.

El contraargument és bo i cal posar-lo: core.fsmonitor és per naturalesa un ajust per repositori —existeix per accelerar arbres enormes, i cada arbre és diferent— i ficar-lo en configuració protegida el deixaria gairebé inservible. Per això tant la nota de la CSA com la divulgació original posen l'arreglament on toca: que sigui l'agent qui cridi git amb -c core.fsmonitor=false. D'acord. El que no se sosté és la coda tranquil·litzadora que això és «una fallada dels agents d'IA» i ja està: l'ajust que executa programes el llegeix git, d'un fitxer que venia dins del ZIP, i els agents només van ser els primers a cridar git prou de pressa com perquè es notés.

El control existia. Corria en segon lloc

Els quatre registres, independentment del que calgui fer per disparar cadascun, descriuen la mateixa coreografia amb paraules semblants. En el de Codex de 9,8: el programa corre «without a workspace-trust prompt, command approval, or interaction with a model». En el de 7,3: «outside Codex's command sandbox and without a user-approval prompt». En el de goose, ja citat, abans de cap prompt, model, aprovació d'eina o diàleg de confiança. I a Hermes, encara que calgui enviar un missatge, el que executa l'ordre no és el model responent: és el refresc de l'índex que l'agent llança per preparar la resposta.

El que crida l'atenció no és que faltés el control: és que hi era. Els quatre productes tenen el seu diàleg de «confies en aquesta carpeta?» i el seu sandbox d'ordres. I tots quatre recollien context amb git abans de preguntar, perquè preguntar sense saber què hi ha al davant queda lleig. Un control que s'executa després d'allò que pretén controlar no és un control: és documentació. Això no va d'agents d'IA, va de l'ordre de les operacions, i és el mateix error que converteix un diàleg d'elevació en un adorn quan l'instal·lador ja ha copiat el fitxer.

«Actualitza l'agent» no és una resposta quan no hi ha pedaç

Els quatre CVE són part d'un conjunt més gran. Segons la nota de recerca que va publicar la Cloud Security Alliance el 4 de setembre del 2026 sobre la divulgació de Manifold Security, són vuit troballes en set agents, comunicades als fabricants entre el 26 de juny i el 20 de juliol del 2026. Claude Code hi apareix com a vulnerable a la 2.1.193 i corregit a la 2.1.196; Cursor, també corregit, tancat com a duplicat d'un informe intern. I, segons aquella mateixa nota, quatre dels vuit camins seguien sense pedaç el dia de la publicació, amb Qwen Code confirmat vulnerable a 0.19.6 i 0.22.3 i Grok Build a 0.2.93 i 1.0.13.

Aquesta xifra —la meitat sense corregir— és la que converteix un butlletí en una pregunta de gestió. Si el remei fos «actualitza», n'hi hauria prou amb la teva eina de pedaços. Com que la meitat no té on actualitzar-se, l'únic que serveix és saber quins agents hi ha instal·lats, en quina versió i en quins portàtils. I aquesta llista, quan ens asseiem a demanar-la, gairebé mai no existeix: els agents van entrar un a un, instal·lats per la persona que els anava a fer servir, amb la seva pròpia clau de proveïdor i sense passar per ningú.

Què mirar dilluns, sense esperar ningú

Llegir la configuració no executa res; el que executa és git status i git diff. Així que, en una carpeta que no hagi arribat per clone, això es pot fer abans d'obrir-la amb cap eina:

git -C /ruta/al/repo config --local --includes --list \
  | grep -Ei 'fsmonitor|hookspath|sshcommand|credential\.helper|^filter\.|^attr\.tree|
              textconv|\.driver=|^alias\.|^include|pager|external'

El --includes no és decoratiu, i és la part d'aquest post que més ens va costar veure. Si l'omets, el teu grep menteix. La documentació de git config diu que aquella opció «Defaults to off when a specific file is given (e.g., using --file, --global, etc) and on when searching all config files», i --local és un àmbit concret: per defecte, no segueix les directives include. N'hi ha prou que el .git/config rebut tingui un [include] path = un-altre-fitxer i hi fiqui el fsmonitor perquè la teva comprovació surti neta i git status executi el programa igualment.

Si surt qualsevol cosa, no la negociïs: la configuració rebuda s'aparta sencera i se n'escriu una de nova. I si has de mirar l'estat d'un repositori del qual dubtes, l'opció -c de la línia d'ordres guanya la configuració del repositori. Ho diu el manual de git sense giragonses: «Pass a configuration parameter to the command. The value given will override values from configuration files».

mv /ruta/al/repo/.git/config /ruta/al/repo/.git/config.recibido
git -C /ruta/al/repo -c core.fsmonitor= status

Honestedat al davant, perquè això és el que separa un consell d'un placebo: la segona línia és un apedaçament per clau, no una frontera. Neutralitza core.fsmonitor i no et protegeix d'attr.tree ni de la pròxima clau que algú trobi, i el grep de dalt tampoc no és una llista tancada —la mateixa nota de la CSA assenyala a més core.hooksPath, credential.helper i les eines externes de diff i merge—. La frontera de debò és la primera línia de la caixa: si la carpeta no va arribar per clone, el seu .git és contingut d'un tercer i es tracta com a tal. La resta és anar tapant forats d'un en un.

Un agent és un sistema de producció, no una extensió

A everyWAN tenim automatització pròpia amb n8n autoallotjat fent tasques internes en producció, i la tractem com el que és: inventariada, amb un responsable i amb finestra d'actualització. No perquè siguem especialment disciplinats, sinó perquè quan una peça així cau o es torça, no es nota en una pantalla: es nota en el que deixa de passar. Un agent de codi al portàtil d'un desenvolupador és la mateixa categoria de cosa, amb un agreujant: corre amb la sessió d'una persona que té claus de núvol, accés al repositori de l'empresa i permís per fer push. De quin nom acaba al registre d'auditoria quan un agent fa servir el token d'algú ja en vam escriure; aquest cas és l'esglaó anterior, quan l'agent ni tan sols ha començat a treballar.

I el conflicte d'interès al davant: everyWAN viu de la consultoria i dels serveis gestionats, i posar ordre en això es factura. La part comprovable d'aquest post és la que va entre cometes i enllaçada al final; el grep de dalt el pot passar qualsevol aquest matí sense nosaltres, i és exactament el que recomanem fer abans de demanar pressupost a ningú, nosaltres inclosos.

Fonts (verificades el 5 d'octubre del 2026): les descripcions, dates de publicació, puntuacions CVSS, vectors, versions afectades i corregides i les frases citades dels quatre expedients — NVD: CVE-2026-19592 i CVE-2026-19593 (tots dos publicats l'1 de setembre del 2026, CWE-15), CVE-2026-72718 (10 d'agost del 2026, CWE-94, corregit a goose 1.44.0) i CVE-2026-71963 (3 de setembre del 2026, CWE-78). Les definicions de core.fsmonitor i attr.tree, l'apartat de configuració protegida, la frase sobre la negativa a llegir la configuració d'un repositori aliè i la regla de precedència entre fitxers — documentació oficial de git-config. El recompte de vuit troballes en set agents, el calendari de notificació als fabricants, les versions de Claude Code, Cursor, Qwen Code i Grok Build, la dada dels quatre camins sense pedaç i l'enumeració citada de les vies de lliurament — nota de recerca de la Cloud Security Alliance del 4 de setembre del 2026 sobre la divulgació de Manifold Security. La frase sobre l'opció -c — manual de git. El recompte de tres opcions amb configuració protegida és nostre, fet sobre els 97 fitxers de Documentation/config/ de la branca principal del repositori de git. Fotografia de portada: «External hard drive connected laptop», de Markus Spiske, via rawpixel i Openverse, domini públic (CC0).

Quins agents d'IA hi ha instal·lats a la teva empresa, i en quina versió?

No quantes llicències: què corre a cada lloc de treball, amb quina clau i amb accés a què. Muntem l'inventari de la capa d'automatització i IA, li posem un responsable i finestra d'actualització, i deixem escrit què pot tocar cada agent sota criteri Zero Trust, incloses les carpetes que arriben de fora.

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