All vulnerabilities
GHSA-c85g-q5w4-ff68

getgrav/grav: Page authors can capture visitors' HTTP Basic credentials through Twig in page content

getgrav/grav
CVSS
n/aMedium
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)No scoreNo FIRST EPSS score in this snapshot yet
Fixed in2.2.5Fixed versionGitHub
Published7 Oct 2026Updated 7 Oct 2026GitHub

What fixes it

  • 2.2.5getgrav/grav, composerGitHubcomposer require "getgrav/grav:^2.2.5"

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

Summary

On a site where visitors authenticate with HTTP Basic credentials, a user who can only write pages could add Twig to page content that reads the Basic username and password of whoever views the page, and sends them to a host of the author's choosing. Sites that do not use HTTP Basic authentication are not affected.

Affected versions

Grav 2.0.0 through 2.2.4. From 2.0.19 Twig in page content is on by default, so every page writer can use it. On 2.0.0 to 2.0.18 only sites that had turned on security.twig_content.process_enabled are affected. Grav 1.7 has no content sandbox, so page authors there already have unrestricted Twig and there is no boundary for this issue to cross.

Details

Grav built the current request's Uri object with the visitor's Basic credentials taken from PHP's PHP_AUTH_USER and PHP_AUTH_PW, which PHP fills from the Authorization: Basic header. Uri::toArray() returned them as user and pass, and Uri::__toString() wrote them into the address as user:pass@host.

The Twig content sandbox allows toarray and __tostring on Grav\Common\Uri, so page content could print the credentials with {{ uri.toarray.pass }} or simply {{ uri }}, as well as through url(uri), uri|array and uri|yaml_encode. The original report names toArray(); printing the object is enough. Placed inside an inline style that loads a background image from another host, the value is sent there when the visitor's browser loads the page.

On versions before 2.0.25 the rendered result was also stored in the shared page cache, so one visitor's credentials could be served to later visitors.

Impact

A page author learns the HTTP Basic username and password of other visitors, including administrators. This matters where each visitor has their own Basic credentials, for example a per-user htpasswd file or Basic authentication backed by LDAP or another directory, where the password may also open other systems. Where a single shared Basic password is already known to every author, nothing new is exposed.

Patches

Fixed in Grav 2.2.5. The request Uri no longer carries the visitor's Basic credentials, so nothing in page content or in a theme can print them. Uri::user() and Uri::password() are now empty for the current request; code that needs the Basic credentials should read them from the server variables directly. No configuration change is needed, including on sites with their own security.twig_sandbox allowlist.

Credits

Reported by @baeseungwon1010.

Text from GitHub Advisory Database

Affected versions 1

  • getgrav/grav, composer>= 2.0.0, < 2.2.5GitHub