
Gitea precedente alla 1.27.1 consente l'esecuzione di codice remoto tramite l'API diffpatch attraverso l'installazione di Git hook.
[!WARNING] Questo repository è destinato esclusivamente alla ricerca di sicurezza autorizzata e a test di laboratorio controllati. Non eseguire il proof of concept contro sistemi di cui non si è proprietari o per i quali non si dispone di esplicita autorizzazione alla valutazione.
CVE-2026-60004 è una vulnerabilità critica di esecuzione di codice remoto nell'API diffpatch di Gitea. Un utente autenticato con permesso di creare o scrivere su un repository può inviare una patch appositamente predisposta che causa la materializzazione di un hook Git eseguibile all'interno di un repository bare temporaneo. Quando l'hook viene attivato, i comandi controllati dall'attaccante vengono eseguiti con i privilegi dell'account di servizio Gitea.
Se la registrazione pubblica è abilitata, un attaccante non autenticato potrebbe essere in grado di creare un account e raggiungere l'endpoint autenticato vulnerabile.
| Attributo | Dettagli |
|---|
| Identificatore | CVE-2026-60004 |
| Advisory | GHSA-rcr6-4jqh-j84m |
| Gravità | Critica — CVSS 3.1: 9.8 |
| Debolezza | CWE-94: Controllo improprio della generazione di codice |
| Versioni interessate | Gitea dalla 1.17.0 alla 1.27.0 |
| Versione corretta | Gitea 1.27.1 |
| Accesso richiesto | Accesso in scrittura al repository |
| Contesto di esecuzione | Account del sistema operativo di Gitea |
| Data CISA KEV | 2026-08-25 |
| File | Descrizione |
|---|---|
gitea_diffpatch_rce.py | Proof of concept basato solo sulla libreria standard che si autentica, crea un repository privato, invia la patch appositamente predisposta e recupera l'output dei comandi. |
payload.patch | Patch di esempio che crea un hook eseguibile hooks/post-index-change. |
poc.png | Screenshot catturato durante la validazione in laboratorio. |
README.md | Note di ricerca originali. |
Il proof of concept è stato validato nel seguente ambiente isolato:
| Componente | Configurazione |
|---|---|
| Gitea | 1.27.0 |
| Git | 2.47.2 |
| Distribuzione | Container Docker denominato gitea-lab |
| Indirizzo del servizio | 192.168.184.128:3000 |
| Identità osservata | uid=1000(git) gid=1000(git) |
Lo sfruttamento riuscito ha prodotto un output dei comandi simile a:
uid=1000(git) gid=1000(git) groups=1000(git)
Linux 6.12.20-amd64 x86_64
/data/gitea/tmp/local-repo/upload.git630501597
[exit-status=0]

Lo script utilizza solo la libreria standard di Python e non richiede pacchetti aggiuntivi.
python3 gitea_diffpatch_rce.py <base_url> <username> <password> "<command>"
Esempio per un'istanza di laboratorio locale:
python3 gitea_diffpatch_rce.py \
http://127.0.0.1:3000 \
pocuser \
'P@ssw0rd!' \
'id; uname -a'
Lo script tenta prima la registrazione web, poi si autentica con le credenziali fornite. Ciò consente allo stesso comando di funzionare sia con un nuovo account su un'istanza con registrazione aperta sia con un account esistente.
La catena di sfruttamento è composta da quattro fasi:
Invio della patch controllata dall'attaccante
POST /api/v1/repos/{owner}/{repo}/diffpatch applica il contenuto della patch fornito
utilizzando git apply --index --recount --cached --binary --ignore-whitespace --whitespace=fix -3 all'interno di un clone temporaneo.
Posizionamento del percorso dell'hook
Il repository temporaneo viene creato come clone bare e condiviso. In un repository
bare, la radice del repository è anche $GIT_DIR; di conseguenza, il percorso della patch
hooks/post-index-change viene risolto all'interno della directory degli hook attivi di Git.
Materializzazione dell'hook eseguibile
La stessa patch viene inviata due volte. La seconda applicazione produce un
conflitto add/add, causando il fallback a tre vie che materializza il percorso su
disco con modalità 100755, nonostante l'uso di --cached. Un successivo aggiornamento dell'indice
invoca post-index-change, eseguendo il codice shell iniettato come
account di servizio Gitea.
Recupero dell'output nativo di Git
L'hook identifica il repository di origine tramite
objects/info/alternates, memorizza l'output dei comandi come blob Git, crea
un tree e un commit, e aggiorna refs/heads/output-leak. Il proof of concept
recupera quindi il risultato tramite l'API dei file raw di Gitea. Questa tecnica
non richiede una connessione in uscita diretta dal target.
Lo sfruttamento riuscito concede l'esecuzione di comandi con i privilegi dell'account di servizio Gitea. A seconda della configurazione di distribuzione, un attaccante potrebbe essere in grado di accedere a:
app.ini e credenziali del databaseSECRET_KEY, INTERNAL_TOKEN e segreti relativi a LFSÈ stato confermato che l'account di laboratorio aveva accesso in lettura a app.ini.
I difensori dovrebbero investigare i seguenti artefatti e pattern di richieste:
/api/v1/repos/*/*/diffpatch in rapida successioneoutput-leakpoc <[email protected]>hooks/post-index-change in repository
bare o directory di clone temporanee/data/gitea/tmp/local-repo/upload.git*Questi indicatori descrivono il proof of concept incluso e non sono esaustivi; un exploit modificato potrebbe utilizzare percorsi, ref, identità o canali di output diversi.
/api/v1/.../diffpatch corrispondenti. Validare la regola
rispetto alle integrazioni legittime prima della distribuzione.DISABLE_REGISTRATION=true se
non è operativamente necessaria. Ciò riduce la raggiungibilità non autenticata ma
non protegge dagli utenti esistenti con accesso in scrittura al repository.Per il container di laboratorio utilizzato in questa ricerca, la dismissione può essere eseguita con:
docker rm -f gitea-lab
Questo materiale è fornito per aiutare i difensori a riprodurre, comprendere, rilevare e correggere la vulnerabilità. Gli operatori dovrebbero testare solo in ambienti isolati e seguire i requisiti di autorizzazione e divulgazione della propria organizzazione.