GHSA-H8VQ-8GPG-MHCG
Vulnerability from github – Published: 2026-06-30 18:43 – Updated: 2026-06-30 18:43Description
This is a residual bypass of CVE-2026-46635 / GHSA-vcc8-phrv-43wj that only affects sandboxing enabled through SourcePolicyInterface (and not the regular global sandbox mode).
CoreExtension::column() receives the active sandbox state via the needs_is_sandboxed channel as a boolean $isSandboxed, but then routes the per-element property reads through SandboxExtension::checkPropertyAllowed() without forwarding the current Source. SandboxExtension::checkPropertyAllowed() re-evaluates isSandboxed($source) internally; with $source = null the SourcePolicyInterface-driven decision is lost, the method short-circuits to "not sandboxed", and the property allowlist is never consulted.
A template author whose sandbox is gated by a SourcePolicyInterface and who has column on their allowedFilters list can therefore read any public or magic property of any object reachable in the render context, regardless of SecurityPolicy::$allowedProperties. Direct attribute access to the same property is blocked, and the same payload is also blocked under global sandbox mode, which makes this a clear policy enforcement gap rather than a configuration issue.
Resolution
CoreExtension::column() no longer goes through the SandboxExtension wrapper for the property check. It calls the security policy directly: the per-source decision is already captured by the $isSandboxed boolean computed at the call site, so the property allowlist is enforced consistently for both global and source-policy sandboxing.
Credits
Twig would like to thank Vincent55 Yang for reporting the issue and Fabien Potencier for providing the fix.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.26.0"
},
"package": {
"ecosystem": "Packagist",
"name": "twig/twig"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.27.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-48808"
],
"database_specific": {
"cwe_ids": [
"CWE-693",
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-30T18:43:45Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "### Description\n\nThis is a residual bypass of CVE-2026-46635 / GHSA-vcc8-phrv-43wj that only affects sandboxing enabled through `SourcePolicyInterface` (and not the regular global sandbox mode).\n\n`CoreExtension::column()` receives the active sandbox state via the `needs_is_sandboxed` channel as a boolean `$isSandboxed`, but then routes the per-element property reads through `SandboxExtension::checkPropertyAllowed()` without forwarding the current `Source`. `SandboxExtension::checkPropertyAllowed()` re-evaluates `isSandboxed($source)` internally; with `$source = null` the `SourcePolicyInterface`-driven decision is lost, the method short-circuits to \"not sandboxed\", and the property allowlist is never consulted.\n\nA template author whose sandbox is gated by a `SourcePolicyInterface` and who has `column` on their `allowedFilters` list can therefore read any public or magic property of any object reachable in the render context, regardless of `SecurityPolicy::$allowedProperties`. Direct attribute access to the same property is blocked, and the same payload is also blocked under global sandbox mode, which makes this a clear policy enforcement gap rather than a configuration issue.\n\n### Resolution\n\n`CoreExtension::column()` no longer goes through the `SandboxExtension` wrapper for the property check. It calls the security policy directly: the per-source decision is already captured by the `$isSandboxed` boolean computed at the call site, so the property allowlist is enforced consistently for both global and source-policy sandboxing.\n\n### Credits\n\nTwig would like to thank Vincent55 Yang for reporting the issue and Fabien Potencier for providing the fix.",
"id": "GHSA-h8vq-8gpg-mhcg",
"modified": "2026-06-30T18:43:45Z",
"published": "2026-06-30T18:43:45Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/twigphp/Twig/security/advisories/GHSA-h8vq-8gpg-mhcg"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/twig/twig/CVE-2026-48808.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/twigphp/Twig"
},
{
"type": "WEB",
"url": "https://github.com/twigphp/Twig/releases/tag/v3.27.0"
},
{
"type": "WEB",
"url": "https://symfony.com/blog/cve-2026-48808-sandbox-property-allowlist-bypass-via-the-column-filter-under-sourcepolicyinterface"
}
],
"schema_version": "1.4.0",
"severity": [],
"summary": "Twig: Sandbox property allowlist bypass via the `column` filter under `SourcePolicyInterface`"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.