{"id":"CVE-2026-46633","kind":"vulnerability","aliases":["CVE-2026-46633","GHSA-7p85-w9px-jpjp"],"related":[],"title":"Twig: PHP code injection via `{% use %}` template name","description":"### Description\n\n`Compiler::string()` escapes `\"`, `$`, `\\`, NUL and TAB when generating PHP double-quoted string literals, but does not escape single quotes. In `ModuleNode::compileConstructor()`, the template name from a `{% use %}` tag is compiled via `subcompile()` -> `string()` and placed inside a surrounding PHP single-quoted string literal. A template name containing a single quote terminates that surrounding string early, allowing arbitrary PHP expressions to be injected into the compiled cache file.\n\nThe injected code executes within the PHP process when the cache file is first loaded, bypassing the Twig sandbox entirely and achieving remote code execution. `SecurityPolicy` unconditionally allows `{% use %}` regardless of the configured `allowedTags`, so this primitive is reachable from sandboxed templates as well.\n\n### Resolution\n\n`Compiler::string()` now also escapes single quotes so that template names placed inside single-quoted PHP literals can no longer break out of the surrounding context.\n\n### Credits\n\nTwig would like to thank Anvil Secure in collaboration with Claude and Anthropic Research for reporting the issue and providing the fix.","summary":"Twig's compiler fails to escape single quotes in template names used by the {% use %} tag, so a crafted name breaks out of a generated PHP string. The injected PHP runs when the compiled cache file is first loaded, which lets an attacker run code on the server even inside Twig's sandbox.","severity":"critical","cvss":9.8,"epss":0.00688,"exploited":false,"exploited_at":null,"products":[{"name":"twig/twig","fixed":["3.26.0"],"affected":">= 1.15.1, < 3.26.0","ecosystem":"composer"},{"name":"symfony twig","fixed":["3.26.0"],"affected":"< 3.26.0","ecosystem":"vendor"}],"ecosystems":["composer","vendor"],"tags":["composer","cwe-94","laravel","package","php","symfony","twig"],"not_affected_if":["no-untrusted-template-names","twig-3.26.0-or-later","twig-below-1.15.1"],"how_to_check":"- Check the installed version with `composer show twig/twig` and look at the version line.\n- Look in composer.lock for `twig/twig` and note the version.\n- Treat any version from `1.15.1` up to, but not including, `3.26.0` as exposed.","fix":"- Upgrade `twig/twig` to `3.26.0`.","status":"open","published_at":"2026-05-21T21:24:53+00:00","first_seen_at":"2026-11-04T00:01:24+00:00","triaged_at":"2026-11-04T00:01:55+00:00","updated_at":"2026-11-04T00:16:19+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-04T00:01:55Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade `twig/twig` to `3.26.0`.","reach":"unknown","title":"Twig: a crafted {% use %} template name runs PHP code","impact":"high","summary":"Twig's compiler fails to escape single quotes in template names used by the {% use %} tag, so a crafted name breaks out of a generated PHP string. The injected PHP runs when the compiled cache file is first loaded, which lets an attacker run code on the server even inside Twig's sandbox.","audience":"developers","category":"package","nicknames":[],"who_cares":["twig","php","composer","symfony","laravel"],"confidence":0.8,"fix_status":"available","needs_auth":"unknown","worst_case":"code runs on the server as the PHP process user","analyst_note":"","how_to_check":"- Check the installed version with `composer show twig/twig` and look at the version line.\n- Look in composer.lock for `twig/twig` and note the version.\n- Treat any version from `1.15.1` up to, but not including, `3.26.0` as exposed.","plain_action":"","needs_analyst":false,"not_affected_if":["twig-below-1.15.1","twig-3.26.0-or-later","no-untrusted-template-names"],"who_is_affected":"Applications that use the Twig PHP template engine at versions from 1.15.1 up to 3.26.0 are exposed. The risk is highest where template names can come from untrusted input, including sandboxed templates, since the sandbox does not block {% use %}. Projects that only render fixed templates they wrote themselves are less exposed but should still upgrade.","user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"critical"},"cost_usd":0.000746,"input_tokens":4559,"output_tokens":581,"severity_before":"critical"},"analyst_status":null,"analyst_note":null,"search":"'-2026':10A,18A '-46633':11A,19A '-94':25B '7p85':14A 'achiev':176C 'allow':143C,182C 'allowedtag':188C 'also':203C 'anthrop':240C 'anvil':233C 'arbitrari':144C 'attack':73B 'break':51B,221C 'bypass':170C 'cach':65B,153C,165C 'claud':238C 'code':3A,75B,157C,178C 'collabor':236C 'compil':33B,64B,85C,116C,152C,200C 'compileconstructor':107C 'compos':23B 'configur':187C 'contain':134C 'context':226C 'craft':49B 'credit':227C 'cve':9A,17A 'cwe':24B 'descript':84C 'doubl':95C 'double-quot':94C 'earli':142C 'entir':174C 'escap':36B,87C,102C,204C 'even':79B 'execut':158C,179C 'express':146C 'fail':34B 'file':66B,154C,166C 'first':68B,168C 'fix':249C 'generat':55B,92C 'ghsa':13A 'ghsa-7p85-w9px-jpjp':12A 'inject':4A,59B,149C,156C 'insid':80B,122C,212C 'issu':245C 'jpjp':16A 'laravel':26B 'let':71B 'like':230C 'liter':98C,130C,217C 'load':69B,169C 'longer':220C 'modulenod':106C 'name':8A,41B,50B,110C,133C,210C 'nul':88C 'packag':27B 'php':2A,28B,56B,60B,93C,125C,145C,161C,216C 'place':121C,211C 'primit':191C 'process':162C 'provid':247C 'quot':38B,96C,104C,128C,137C,206C,215C 'reachabl':193C 'regardless':184C 'remot':177C 'report':243C 'research':241C 'resolut':199C 'run':61B,74B 'sandbox':83B,173C,195C 'secur':234C 'securitypolici':180C 'server':78B 'singl':37B,103C,127C,136C,205C,214C 'single-quot':126C,213C 'string':57B,86C,97C,119C,129C,141C,201C 'subcompil':118C 'surround':124C,140C,225C 'symfoni':29B 'symfony':21A 'tab':90C 'tag':46B,114C 'templat':7A,40B,109C,132C,196C,209C 'termin':138C 'thank':232C 'twig':1A,22A,30B,31B,81B,172C,228C 'twig/twig':20A 'uncondit':181C 'use':6A,42B,45B,113C,183C 'via':5A,117C 'w9px':15A 'well':198C 'within':159C 'would':229C","nicknames":[],"mitigations":[],"who_affected":"Applications that use the Twig PHP template engine at versions from 1.15.1 up to 3.26.0 are exposed. The risk is highest where template names can come from untrusted input, including sandboxed templates, since the sandbox does not block {% use %}. Projects that only render fixed templates they wrote themselves are less exposed but should still upgrade.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["symfonytwig","twig","twigtwig"],"ptokens":["symfony","twig"],"labels":["composer","critical","cwe94","laravel","package","php","symfony","twig","vendor"],"campaign_type":null,"first_public_at":"2026-05-20T07:44:02+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-7p85-w9px-jpjp","url":"https://github.com/advisories/GHSA-7p85-w9px-jpjp","severity":"critical","published_at":"2026-05-21T21:24:53+00:00","modified_at":"2026-11-04T00:00:33+00:00","first_seen_at":"2026-11-04T00:01:24+00:00","fetched_at":"2026-11-04T02:09:26+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-46633","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-46633","severity":null,"published_at":"2026-07-14T22:16:55+00:00","modified_at":"2026-10-24T22:10:00+00:00","first_seen_at":"2026-11-04T00:16:19+00:00","fetched_at":"2026-11-04T00:16:19+00:00","note":null}],"documents":[{"id":61733,"url":"https://api.github.com/repos/twigphp/Twig/security-advisories/GHSA-7p85-w9px-jpjp","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":61734,"url":"https://github.com/twigphp/Twig/security/advisories/GHSA-7p85-w9px-jpjp","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2026-05-20T07:44:02+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":61735,"url":"https://github.com/twigphp/Twig/commit/679447fa29083043665482ccf7d64372472621b8","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":61736,"url":"https://github.com/twigphp/Twig/commit/a2c6db7ea7d2c90923e6708019ec1442526d1c30","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":61737,"url":"https://github.com/twigphp/Twig/commit/e9ff55f6910832428e48a35b2e0748189ad49ae3","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":61738,"url":"https://github.com/twigphp/Twig/releases/tag/v3.26.0","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}