CVE-2026-61842: Grav: Twig sandbox config exfiltration via grav.offsetGet + dump filter (CVE-2026-44738 bypass)

Published Aug 19, 2026
·
Updated

Summary

The Twig content sandbox replaces config with the redacted SandboxConfig facade and strips Config::get/toArray from the method allowlist (GHSA-j274-39qw-32c9), so editor content can't read config secrets via config. That's bypassable: grav is the raw container, offsetget is allow-listed on it, so grav.offsetGet('config') returns the real Config. The allow-listed filters jsonencode/printr/yamlencode then serialize it at the PHP level, never hitting the sandbox method gate, dumping the whole config tree including every plugins. secret (SMTP creds, API keys, plugin DB creds). Incomplete fix for GHSA-j274-39qw-32c9. security.salt does not leak (it lives outside config).

Details

The documented path is blocked: config is the SandboxConfig facade (Twig.php:660) and the raw Config/Data method entries are stripped when configaccess is false, so {{ config.get(...) }} returns the default and {{ grav.offsetGet('config').get(...) }} raises SecurityNotAllowedMethodError.

The bypass uses two allow-listed primitives the redaction doesn't cover:

1. grav.offsetGet('config') returns the raw Config. The SandboxConfig facade replaces only the config variable, not grav['config']; offsetget is allow-listed on Grav\Common\Grav in system/config/security.yaml. 2. jsonencode/printr/yamlencode serialize the object inside the filter and never call GravSecurityPolicy::checkMethodAllowed (GravSecurityPolicy.php:65), so the stripped methods don't matter.

Bug class: object-dumping filters bypass the sandbox member gate. The same dump reaches page/pages/uri/user via their allow-listed accessors; config is the secret-bearing target.

Reachable below the publisher-Twig opt-in: a -prefixed slug is modular (Page.php:228), and Page::content() sets $processtwig = $scantwigxss || $this->modularTwig() (Page.php:816), so a modular child's body Twig is sandboxed-rendered even with twigcontent.processenabled false (the default), while $scantwigxss stays false so the render-time XSS scan (GHSA-2c4f-86xc-cr74) is skipped. Any admin.pages author (or filesystem write to user/pages) exfiltrates config on a stock install. On a regular process.twig page the whole-tree dump trips the XSS scan and is blanked, but a targeted split/slice extraction of one subtree is XSS-clean and survives.

PoC

Sandboxed render, configaccess default false. First two lines show the gate holding, third is the bypass:

twig {{ config.get('plugins.email.mailer.smtp.password', 'DENIED') }} {# => DENIED #} {{ grav.offsetGet('config').get('plugins.email.mailer.smtp.password') }} {# => SecurityNotAllowedMethodError 'get' #} {{ grav.offsetGet('config')|jsonencode }} {# => {...,"plugins":{"email":{"mailer":{"smtp":{"password":"CANARY..."}}}},...} #}

Stock-install reproduction (no user/config/security.yaml):

yaml user/config/plugins/email.yaml -- decoy secret mailer: { smtp: { password: CANARYSMTPPW8b3f1 } }

user/pages/70.parent/default.md --- title: Parent content: { items: '@self.modular' } template: modular ---

twig {# user/pages/70.parent/secret/default.md #} --- title: Secret template: modular/text --- {{ grav.offsetGet('config')|jsonencode }}

bash curl -s http://localhost/parent # body contains CANARYSMTPPW8b3f1

logs/security.log shows no sandbox block and no XSS scan for the route. Verified on Grav 2.0.1 (6f619f0ae), PHP 8.4.22, Twig 3.26.1-DEV.

Impact

A page author (admin.pages, no admin/super) reads the entire config tree: plugin SMTP credentials, API keys, plugin DB credentials. Read-only. Default install; the modular path needs no Twig opt-in.

Fix

system/config/security.yaml: drop offsetget (and get) from twigsandbox.allowedmethods for Grav\Common\Grav -- the legit uses are theme/getversion; offsetget is the raw-container reach. Closes the demonstrated path.

Sandbox-wide: make jsonencode/printr/yamlencode/string refuse non-allow-listed objects when $env->isSandboxed() (mirror the Closure-only guard Twig applies to map/filter/reduce). Closes the class for page/pages/uri/user too.

Other sources

Grav is a file-based Web platform. Prior to 2.0.2, the Grav Twig content sandbox permits grav.offsetGet('config') to return the raw configuration object and permits jsonencode, printr, yamlencode, and string filters to serialize that object without passing through GravSecurityPolicy::checkMethodAllowed. A user with page-author permissions can render sandboxed content that exposes plugins. configuration secrets, including SMTP credentials, API keys, and plugin database credentials. This issue is fixed in version 2.0.2.

MITRE

Affected Software

2 affected componentsFixes available
Grav Grav<2.0.2
composer/getgrav/grav<2.0.2
2.0.2

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade composer/getgrav/grav to a version that resolves this vulnerability.

    Fixed in 2.0.2
  2. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Fixed in 2.0.2
  3. Configuration

    In system/config/security.yaml, remove 'offsetget' (and '__get') from twig_sandbox.allowed_methods for 'Grav\Common\Grav' so that Grav['config'] access via offsetGet is no longer reachable; keep only 'theme' and 'getversion' for Grav\Common\Grav.

    system/config/security.yaml (Twig sandbox) twig_sandbox.allowed_methods[Grav\Common\Grav] (remove offsetget and __get) = drop offsetget (and __get) from twig_sandbox.allowed_methods for Grav\Common\Grav; allowed methods should be only theme/getversion

Event History

Aug 19, 2026
CVE Published
via MITRE·03:23 PM
Data Sourced
via MITRE·03:23 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·04:18 PM
DescriptionSeverityWeakness
Sep 2, 2026
Advisory Published
via GitHub·09:41 PM
Data Sourced
via GitHub·09:41 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Who can exploit this issue?

An attacker needs page-author permissions in Grav. They can use sandboxed content rendering to access the raw configuration object.

2

What information could be exposed?

The issue can expose secrets stored under plugins.* configuration, including SMTP credentials, API keys, and plugin database credentials. The impact is limited to confidentiality; integrity and availability are not affected according to the provided vector.

3

Are unpatched Grav installations affected by default?

The provided information states that Grav versions prior to 2.0.2 are affected, but it does not specify whether a particular default configuration or plugin setup is required. Exposure depends on whether a page author can render sandboxed content and whether sensitive plugin configuration is present.

4

How can I tell whether an installation is affected?

Check whether Grav is running a version earlier than 2.0.2 and whether users with page-author permissions can create or modify sandboxed Twig-rendered content. Also review plugins.* configuration for SMTP credentials, API keys, or database credentials that could be exposed.

5

What is the remediation?

Upgrade Grav to version 2.0.2, which fixes the issue. If upgrading cannot occur immediately, restrict page-author access and prevent untrusted authors from rendering sandboxed content.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203