RunSybil Says a CPython Bug Lets Chat Templates Escape Jinja Sandboxes; Python Security Team Does Not Consider the Escape a CPython Vulnerability
RunSybil says a CPython memory bug lets model chat templates escape Jinja sandboxes; Python's security team does not consider the demonstrated escape a CPython vulnerability. The crash fix shipped in 3.13.16, 3.14.8 and 3.15.0 release candidate 2.
Editor's Note ·
- Clarification:
- The CPython record section says 'user dariushoule opens issue gh-155752' and describes the fix pull request without saying that this is RunSybil's researcher. The backport commit messages credit 'Co-authored-by: Darius Houle <[email protected]>', the blog post is by Darius Houle, and CSO says RunSybil submitted the patch to CPython. The issue, the fix pull request and the RunSybil blog post therefore come from the same party and are not independent of one another; the issue text itself does not mention sandboxes or Jinja.
- Clarification:
- The article says CSO 'adds that the researchers shared proof-of-concept exploits with multiple inference providers' and 'reports a similar recommendation' that hosting providers treat such components as best-effort security controls. CSO attributes both to RunSybil's researchers, and RunSybil's own post makes both statements (the post says 'many inference providers'). CSO's reporting beyond the post is the Python Security Response Team's response to CSO and its statement that the report was sent by email rather than through CPython's private GitHub reporting channel.
Overview
Security firm RunSybil says a memory-safety flaw in CPython can let a malicious AI model’s chat template escape a Jinja sandbox and run code inside an inference server, according to CSO, which published its report on 6 November 2026. The Python Security Response Team (PSRT) told CSO that it acknowledges “the underlying CPython bug reported by RunSybil” but does not consider “the demonstrated sandbox escape to be a CPython security vulnerability”. The underlying bug has a fix, which the changelogs for 3.13.16, 3.14.8 and 3.15.0 release candidate 2 list under Core and Builtins as a crash fix. Times are UTC GitHub timestamps; changelog release dates carry no time zone.
What RunSybil reports
In a blog post dated 3 November 2026, RunSybil’s Darius Houle says the bug “abuses CPython’s handling of generic types”. CPython caches a generic alias’s parameters in a tuple; if an argument gains a __typing_subst__ method after the cache is built, the lookup returns -1. The post says the assertion guarding that case is compiled out of normal release builds, so CPython reads from an invalid position and passes the result to the attacker’s callback as a Python object pointer.
The post says it discusses “a single exploitation path affecting CPython >= 3.14”, which relies on a layout that starts in 3.14: CPython stores a tuple’s cached hash immediately before its element pointers. As a proof of concept, the post says the team made a version of Qwen/Qwen2.5-0.5B-Instruct with a backdoored chat_template.jinja and ran arbitrary code in the serving process when the model was used with an inference engine such as vLLM. CSO adds that the researchers shared proof-of-concept exploits with multiple inference providers that support bring-your-own-model features.
The post also describes responses from other parties, which the Herald has not verified independently. It says DigitalOcean’s isolation fully contained the attack and that AWS implemented a mitigation in AWS Bedrock. It says Hugging Face “did not respond to our attempts to contact them in the 90-day disclosure window” and that vLLM “acknowledged our report but has not decided whether it will offer a mitigation”. It relays a reply from the Jinja maintainers: “Report this to cpython. It’s problem with cpython, not with Jinja.”
What the CPython record shows
- 2026-08-09: a devguide commit adds this sentence to the security policy: “CPython does not support sandboxing untrusted Python code as a security boundary, so escapes from such a sandbox are not vulnerabilities in Python and should be reported to the sandbox’s developers instead.” That is four days before the issue below (the Herald’s own count).
- 2026-08-13, 19:37: user dariushoule opens issue gh-155752, “GenericAlias crashes when an argument gains typing_subst after parameters are cached”. The issue lists 3.15, 3.14, 3.13, 3.12 and 3.11 as tested. In the Herald’s reading it describes a crash and does not mention sandboxes or Jinja.
- 2026-08-14, 05:14: pull request gh-155761 is merged. It raises
TypeErrorwhen the changed argument is not in__parameters__. Its merger, JelleZijlstra, had labelled it on 2026-08-13 for backports to 3.10 through 3.15, and the backport bot reported conflicts for 3.10, 3.11 and 3.12. - 2026-08-14, 08:55: the 3.15 backport is merged.
- 2026-08-16: StanFromIreland removes the 3.10, 3.11 and 3.12 backport labels, commenting “this seems like a regular bug to me”. AlexWaygood replies: “I think we usually backport crashes as far as we can since they can be security vulnerabilities”. StanFromIreland later writes “I don’t think a bug is a vulnerability simply because it causes a segfault” and says the bug “does not seem like something exploitable in code that may exist in the real world”. (All three comments are on pull request gh-155761.)
- 2026-09-08, 02:01: the 3.14 backport and the 3.13 backport are merged.
- 2026-09-30: 3.14.8 and 3.13.16 are released (the date on both changelogs and on the python.org download page); the 3.15.0 release candidate 2 changelog is dated 2026-09-01. Each lists “Fix a crash when a types.GenericAlias argument gains a typing_subst hook after the alias parameters have been cached”.
The 3.12 changelog, whose newest release is 3.12.16 of 2026-10-25, contains no gh-155752 entry (the Herald’s own check of the page on 2026-11-08). The same download page lists 3.12 with “security” maintenance status and end of support in 2028-10.
Where the accounts differ
As CSO reports it, the PSRT’s position is that executing untrusted Python code in a sandbox is outside CPython’s security threat model, and that the fix went into the 3.13, 3.14 and 3.15 branches “as a regular bug fix rather than a security fix”. CSO also reports that the PSRT disputed RunSybil’s suggestion that there was no coordinated remediation process, saying the report was sent by email rather than through CPython’s designated private GitHub vulnerability reporting channel. The security policy says a CVE id is assigned if the PSRT determines a report is a vulnerability.
RunSybil’s post says it has “not found an owner willing to implement a holistic solution for those at risk in the supply chain”. It says CPython declined its request to backport the patch “as a security fix to older supported versions”, and that with much of the AI ecosystem on Python 3.12 the fix may not see adoption “until late 2028 when it reaches its end-of-life date”. It recommends considering “security fix only” CPython versions unsafe for workloads that rely on sandboxed code, template engines and expression evaluators. CSO reports a similar recommendation, that hosting providers treat such components as best-effort security controls.
Jinja’s sandbox documentation says “The Jinja sandbox can be used to render untrusted templates” and also “The sandbox alone is not a solution for perfect security.”
What the sources do not say
- None of the cited sources gives a CVE id for this bug.
- None of the cited sources reports exploitation outside RunSybil’s own demonstration.
- Apart from what RunSybil relays, the cited sources contain no statement about this report from Hugging Face, vLLM or the Pallets Project.
- The cited sources do not report a 3.12 release that contains the fix.