jinjava Sandbox Bypass via JavaType-Based Deserialization
Description
jinjava is a Java-based template engine based on django template syntax, adapted to render jinja templates. Priori to 2.8.1, by using mapper.getTypeFactory().constructFromCanonical(), it is possible to instruct the underlying ObjectMapper to deserialize attacker-controlled input into arbitrary classes. This enables the creation of semi-arbitrary class instances without directly invoking restricted methods or class literals. As a result, an attacker can escape the sandbox and instantiate classes such as java.net.URL, opening up the ability to access local files and URLs(e.g., file:///etc/passwd). With further chaining, this primitive can potentially lead to remote code execution (RCE). This vulnerability is fixed in 2.8.1.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A sandbox bypass in jinjava before 2.8.1 allows an attacker to instantiate arbitrary Java classes via JavaType-based deserialization, leading to file reads, SSRF, and potential RCE.
Vulnerability
Description
jinjava is a Java-based template engine that renders Jinja templates. Prior to version 2.8.1, it suffers from a sandbox bypass vulnerability. The root cause is the ability to abuse mapper.getTypeFactory().constructFromCanonical() to instruct the underlying Jackson ObjectMapper to deserialize attacker-controlled input into arbitrary classes. This bypasses the existing sandbox restrictions that block direct invocation of dangerous methods like getClass() or instantiation of Class objects. An attacker can create semi-arbitrary class instances without using restricted methods or class literals [1][3].
Attack
Vector and Exploitation
The attack surface is exposed through template rendering. A built-in template variable ____int3rpr3t3r____ provides direct access to the JinjavaInterpreter instance. While access to methods on that instance is blocked, accessing its properties remains unrestricted. By traversing from the interpreter to its config field, an attacker can reach an ObjectMapper instance. They can then invoke readValue() with a crafted JavaType (constructed via constructFromCanonical) to deserialize attacker-supplied data into any class, including those not on the sandbox whitelist [3].
Impact
An attacker can escape the sandbox and instantiate classes such as java.net.URL. This enables reading local files (e.g., file:///etc/passwd) and performing Server-Side Request Forgery (SSRF) by creating network-related objects. The advisory notes that with further chaining of gadget objects, this primitive could potentially lead to remote code execution (RCE). The vulnerability thus compromises the confidentiality and integrity of the hosting server [1][3].
Mitigation
The vulnerability is fixed in jinjava version 2.8.1. Users should update immediately. No workarounds are documented. The project is actively maintained, and the fix is available on GitHub [1][2]. The advisory details the specific exploitation path and the sandbox escape mechanism [3].
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
com.hubspot.jinjava:jinjavaMaven | >= 2.8.0, < 2.8.1 | 2.8.1 |
com.hubspot.jinjava:jinjavaMaven | < 2.7.5 | 2.7.5 |
Affected products
1- HubSpot/jinjavav5Range: < 2.8.1
Patches
13 files changed · +22 −0
src/main/java/com/hubspot/jinjava/el/ext/JinjavaBeanELResolver.java+3 −0 modified@@ -79,6 +79,9 @@ public Class<?> getType(ELContext context, Object base, Object property) { @Override public Object getValue(ELContext context, Object base, Object property) { + if (isRestrictedClass(base)) { + return null; + } Object result = super.getValue(context, base, validatePropertyName(property)); return result instanceof Class ? null : result; }
src/test/java/com/hubspot/jinjava/el/ext/JinjavaBeanELResolverTest.java+13 −0 modified@@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableSet; import com.hubspot.jinjava.JinjavaConfig; import com.hubspot.jinjava.el.JinjavaELContext; +import com.hubspot.jinjava.interpret.AutoCloseableSupplier; import com.hubspot.jinjava.interpret.JinjavaInterpreter; import javax.el.ELContext; import javax.el.MethodNotFoundException; @@ -173,4 +174,16 @@ public void itThrowsExceptionWhenPropertyIsRestrictedFromConfig() { .hasMessageStartingWith("Could not find property"); JinjavaInterpreter.popCurrent(); } + + @Test + public void itDoesNotAllowAccessingPropertiesOfInterpreter() { + try ( + AutoCloseableSupplier.AutoCloseableImpl<JinjavaInterpreter> c = JinjavaInterpreter + .closeablePushCurrent(interpreter) + .get() + ) { + assertThat(jinjavaBeanELResolver.getValue(elContext, interpreter, "config")) + .isNull(); + } + } }
src/test/java/com/hubspot/jinjava/interpret/JinjavaInterpreterTest.java+6 −0 modified@@ -600,4 +600,10 @@ public void itOutputsUndefinedVariableError() { assertThat(outputtingErrorInterpreters.getErrors().get(0).getCategoryErrors()) .isEqualTo(ImmutableMap.of("variable", "bar")); } + + @Test + public void itDoesNotAllowAccessingPropertiesOfInterpreter() { + assertThat(jinjava.render("{{ ____int3rpr3t3r____.config }}", new HashMap<>())) + .isEqualTo(""); + } }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-m49c-g9wr-hv6vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-59340ghsaADVISORY
- github.com/HubSpot/jinjava/commit/66df351e7e8ad71ca04dcacb4b65782af820b8b1ghsax_refsource_MISCWEB
- github.com/HubSpot/jinjava/releases/tag/jinjava-2.7.5ghsaWEB
- github.com/HubSpot/jinjava/releases/tag/jinjava-2.8.1ghsax_refsource_MISCWEB
- github.com/HubSpot/jinjava/security/advisories/GHSA-m49c-g9wr-hv6vghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.