VYPR
Critical severityNVD Advisory· Published Jul 19, 2018· Updated Aug 5, 2024

CVE-2017-7481

CVE-2017-7481

Description

Ansible before versions 2.3.1.0 and 2.4.0.0 fails to properly mark lookup-plugin results as unsafe. If an attacker could control the results of lookup() calls, they could inject Unicode strings to be parsed by the jinja2 templating system, resulting in code execution. By default, the jinja2 templating language is now marked as 'unsafe' and is not evaluated.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Ansible 2.3.0 and earlier fail to mark lookup-plugin results as unsafe, allowing Unicode injection into Jinja2 templating and code execution.

Vulnerability

Ansible before versions 2.3.1.0 and 2.4.0.0 fails to properly mark lookup-plugin results as unsafe for Jinja2 templating [1][2]. If an attacker could control the results of lookup() calls, they could inject Unicode strings that the Jinja2 templating engine would evaluate, leading to code execution [2]. All versions prior to the fix are affected [1][3].

Exploitation

An attacker requires the ability to control the data returned by a lookup plugin (e.g., via a crafted variable or when using with_ loops) [4]. No special network position or authentication is required beyond whatever access is needed to supply input to an Ansible playbook or role. The attacker crafts Unicode strings that, when processed by Jinja2, result in arbitrary template evaluation [2].

Impact

Successful exploitation allows arbitrary code execution on the Ansible control node or managed hosts where the template is evaluated [2]. The attacker gains the privilege level of the Ansible process (typically root or a privileged user), leading to full compromise of confidentiality, integrity, and availability [3].

Mitigation

Red Hat released updated packages in RHSA-2017:1244 [1]; Ubuntu published USN-4072-1 [3]. The upstream fix is commit a1886911fcf4b691130cfc70dfc5a5e07c46a3 [4]. Users should upgrade to Ansible 2.3.1.0 or 2.4.0.0 (or later) [2]. For backward compatibility, the allow_unsafe_lookups option can be enabled, though it is not recommended [4]. No workaround other than patching is documented.

AI Insight generated on May 22, 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.

PackageAffected versionsPatched versions
ansiblePyPI
>= 2.3.0.0, < 2.3.1.02.3.1.0
ansiblePyPI
< 2.1.6.02.1.6.0
ansiblePyPI
>= 2.2.0.0, < 2.2.3.02.2.3.0

Affected products

9

Patches

4
a1886911fcf4

Fixing security issue with lookup returns not tainting the jinja2 environment

https://github.com/ansible/ansibleJames CammarataMay 8, 2017via ghsa
4 files changed · +31 3
  • docs/docsite/rst/intro_configuration.rst+14 0 modified
    @@ -86,6 +86,20 @@ different locations::
     Most users will not need to use this feature.  See :doc:`dev_guide/developing_plugins` for more details.
     
     
    +.. _allow_unsafe_lookups:
    +
    +allow_unsafe_lookups
    +====================
    +
    +.. versionadded:: 2.2.3, 2.3.1
    +
    +When enabled, this option allows lookup plugins (whether used in variables as `{{lookup('foo')}}` or as a loop as `with_foo`) to return data that is **not** marked "unsafe". By default, such data is marked as unsafe to prevent the templating engine from evaluating any jinja2 templating language, as this could represent a security risk.
    +
    +This option is provided to allow for backwards-compatibility, however users should first consider adding `allow_unsafe=True` to any lookups which may be expected to contain data which may be run through the templating engine later. For example::
    +
    +    {{lookup('pipe', '/path/to/some/command', allow_unsafe=True)}}
    +
    +
     .. _allow_world_readable_tmpfiles:
     
     allow_world_readable_tmpfiles
    
  • examples/ansible.cfg+7 1 modified
    @@ -281,14 +281,20 @@
     # Controls showing custom stats at the end, off by default
     #show_custom_stats = True
     
    -# Controlls which files to ignore when using a directory as inventory with
    +# Controls which files to ignore when using a directory as inventory with
     # possibly multiple sources (both static and dynamic)
     #inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
     
     # This family of modules use an alternative execution path optimized for network appliances
     # only update this setting if you know how this works, otherwise it can break module execution
     #network_group_modules=['eos', 'nxos', 'ios', 'iosxr', 'junos', 'vyos']
     
    +# When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
    +# a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain
    +# jinja2 templating language which will be run through the templating engine.
    +# ENABLING THIS COULD BE A SECURITY RISK
    +#allow_unsafe_lookups = False
    +
     [privilege_escalation]
     #become=True
     #become_method=sudo
    
  • lib/ansible/constants.py+1 0 modified
    @@ -234,6 +234,7 @@ def load_config_file():
     DEFAULT_INVENTORY_IGNORE  = get_config(p, DEFAULTS, 'inventory_ignore_extensions', 'ANSIBLE_INVENTORY_IGNORE', ["~", ".orig", ".bak", ".ini", ".cfg", ".retry", ".pyc", ".pyo"], value_type='list')
     DEFAULT_VAR_COMPRESSION_LEVEL = get_config(p, DEFAULTS, 'var_compression_level', 'ANSIBLE_VAR_COMPRESSION_LEVEL', 0, value_type='integer')
     DEFAULT_INTERNAL_POLL_INTERVAL = get_config(p, DEFAULTS, 'internal_poll_interval', None, 0.001, value_type='float')
    +DEFAULT_ALLOW_UNSAFE_LOOKUPS = get_config(p, DEFAULTS, 'allow_unsafe_lookups', None, False, value_type='boolean')
     ERROR_ON_MISSING_HANDLER  = get_config(p, DEFAULTS, 'error_on_missing_handler', 'ANSIBLE_ERROR_ON_MISSING_HANDLER', True, value_type='boolean')
     SHOW_CUSTOM_STATS = get_config(p, DEFAULTS, 'show_custom_stats', 'ANSIBLE_SHOW_CUSTOM_STATS', False, value_type='boolean')
     
    
  • lib/ansible/template/__init__.py+9 2 modified
    @@ -251,6 +251,9 @@ def __init__(self, loader, shared_loader_obj=None, variables=dict()):
                 loader=FileSystemLoader(self._basedir),
             )
     
    +        # the current rendering context under which the templar class is working
    +        self.cur_context = None
    +
             self.SINGLE_VAR = re.compile(r"^%s\s*(\w*)\s*%s$" % (self.environment.variable_start_string, self.environment.variable_end_string))
     
             self.block_start    = self.environment.block_start_string
    @@ -564,6 +567,7 @@ def _lookup(self, name, *args, **kwargs):
     
             if instance is not None:
                 wantlist = kwargs.pop('wantlist', False)
    +            allow_unsafe = kwargs.pop('allow_unsafe', C.DEFAULT_ALLOW_UNSAFE_LOOKUPS)
     
                 from ansible.utils.listify import listify_lookup_plugin_terms
                 loop_terms = listify_lookup_plugin_terms(terms=args, templar=self, loader=self._loader, fail_on_undefined=True, convert_bare=False)
    @@ -577,7 +581,8 @@ def _lookup(self, name, *args, **kwargs):
                         raise AnsibleError("An unhandled exception occurred while running the lookup plugin '%s'. Error was a %s, original message: %s" % (name, type(e), e))
                     ran = None
     
    -            if ran:
    +            if ran and not allow_unsafe:
    +                from ansible.vars.unsafe_proxy import UnsafeProxy, wrap_var
                     if wantlist:
                         ran = wrap_var(ran)
                     else:
    @@ -589,6 +594,8 @@ def _lookup(self, name, *args, **kwargs):
                             else:
                                 ran = wrap_var(ran)
     
    +                if self.cur_context:
    +                    self.cur_context.unsafe = True
                 return ran
             else:
                 raise AnsibleError("lookup plugin (%s) not found" % name)
    @@ -645,7 +652,7 @@ def do_template(self, data, preserve_trailing_newlines=True, escape_backslashes=
     
                 jvars = AnsibleJ2Vars(self, t.globals)
     
    -            new_context = t.new_context(jvars, shared=True)
    +            self.cur_context = new_context = t.new_context(jvars, shared=True)
                 rf = t.root_render_func(new_context)
     
                 try:
    
ed56f51f185a

Fixing security issue with lookup returns not tainting the jinja2 environment

https://github.com/ansible/ansibleJames CammarataMay 8, 2017via ghsa
4 files changed · +31 3
  • docs/docsite/rst/intro_configuration.rst+14 0 modified
    @@ -86,6 +86,20 @@ different locations::
     Most users will not need to use this feature.  See :doc:`dev_guide/developing_plugins` for more details.
     
     
    +.. _allow_unsafe_lookups:
    +
    +allow_unsafe_lookups
    +====================
    +
    +.. versionadded:: 2.2.3, 2.3.1
    +
    +When enabled, this option allows lookup plugins (whether used in variables as `{{lookup('foo')}}` or as a loop as `with_foo`) to return data that is **not** marked "unsafe". By default, such data is marked as unsafe to prevent the templating engine from evaluating any jinja2 templating language, as this could represent a security risk.
    +
    +This option is provided to allow for backwards-compatibility, however users should first consider adding `allow_unsafe=True` to any lookups which may be expected to contain data which may be run through the templating engine later. For example::
    +
    +    {{lookup('pipe', '/path/to/some/command', allow_unsafe=True)}}
    +
    +
     .. _allow_world_readable_tmpfiles:
     
     allow_world_readable_tmpfiles
    
  • examples/ansible.cfg+7 1 modified
    @@ -282,7 +282,7 @@
     # Controls showing custom stats at the end, off by default
     #show_custom_stats = True
     
    -# Controlls which files to ignore when using a directory as inventory with
    +# Controls which files to ignore when using a directory as inventory with
     # possibly multiple sources (both static and dynamic)
     #inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
     
    @@ -294,6 +294,12 @@
     # Setting to True keeps them under the ansible_facts namespace, the default is False
     #restrict_facts_namespace: True
     
    +# When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
    +# a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain
    +# jinja2 templating language which will be run through the templating engine.
    +# ENABLING THIS COULD BE A SECURITY RISK
    +#allow_unsafe_lookups = False
    +
     [privilege_escalation]
     #become=True
     #become_method=sudo
    
  • lib/ansible/constants.py+1 0 modified
    @@ -236,6 +236,7 @@ def load_config_file():
                                            ["~", ".orig", ".bak", ".ini", ".cfg", ".retry", ".pyc", ".pyo"], value_type='list')
     DEFAULT_VAR_COMPRESSION_LEVEL = get_config(p, DEFAULTS, 'var_compression_level', 'ANSIBLE_VAR_COMPRESSION_LEVEL', 0, value_type='integer')
     DEFAULT_INTERNAL_POLL_INTERVAL = get_config(p, DEFAULTS, 'internal_poll_interval', None, 0.001, value_type='float')
    +DEFAULT_ALLOW_UNSAFE_LOOKUPS = get_config(p, DEFAULTS, 'allow_unsafe_lookups', None, False, value_type='boolean')
     ERROR_ON_MISSING_HANDLER  = get_config(p, DEFAULTS, 'error_on_missing_handler', 'ANSIBLE_ERROR_ON_MISSING_HANDLER', True, value_type='boolean')
     SHOW_CUSTOM_STATS = get_config(p, DEFAULTS, 'show_custom_stats', 'ANSIBLE_SHOW_CUSTOM_STATS', False, value_type='boolean')
     NAMESPACE_FACTS = get_config(p, DEFAULTS, 'restrict_facts_namespace', 'ANSIBLE_RESTRICT_FACTS', False, value_type='boolean')
    
  • lib/ansible/template/__init__.py+9 2 modified
    @@ -252,6 +252,9 @@ def __init__(self, loader, shared_loader_obj=None, variables=dict()):
                 loader=FileSystemLoader(self._basedir),
             )
     
    +        # the current rendering context under which the templar class is working
    +        self.cur_context = None
    +
             self.SINGLE_VAR = re.compile(r"^%s\s*(\w*)\s*%s$" % (self.environment.variable_start_string, self.environment.variable_end_string))
     
             self._clean_regex   = re.compile(r'(?:%s|%s|%s|%s)' % (
    @@ -574,6 +577,7 @@ def _lookup(self, name, *args, **kwargs):
     
             if instance is not None:
                 wantlist = kwargs.pop('wantlist', False)
    +            allow_unsafe = kwargs.pop('allow_unsafe', C.DEFAULT_ALLOW_UNSAFE_LOOKUPS)
     
                 from ansible.utils.listify import listify_lookup_plugin_terms
                 loop_terms = listify_lookup_plugin_terms(terms=args, templar=self, loader=self._loader, fail_on_undefined=True, convert_bare=False)
    @@ -588,7 +592,8 @@ def _lookup(self, name, *args, **kwargs):
                                            "original message: %s" % (name, type(e), e))
                     ran = None
     
    -            if ran:
    +            if ran and not allow_unsafe:
    +                from ansible.vars.unsafe_proxy import UnsafeProxy, wrap_var
                     if wantlist:
                         ran = wrap_var(ran)
                     else:
    @@ -600,6 +605,8 @@ def _lookup(self, name, *args, **kwargs):
                             else:
                                 ran = wrap_var(ran)
     
    +                if self.cur_context:
    +                    self.cur_context.unsafe = True
                 return ran
             else:
                 raise AnsibleError("lookup plugin (%s) not found" % name)
    @@ -656,7 +663,7 @@ def do_template(self, data, preserve_trailing_newlines=True, escape_backslashes=
     
                 jvars = AnsibleJ2Vars(self, t.globals)
     
    -            new_context = t.new_context(jvars, shared=True)
    +            self.cur_context = new_context = t.new_context(jvars, shared=True)
                 rf = t.root_render_func(new_context)
     
                 try:
    
f0e348f5eeb7

Fixing security issue with lookup returns not tainting the jinja2 environment

https://github.com/ansible/ansibleJames CammarataMay 8, 2017via ghsa
4 files changed · +29 2
  • docsite/rst/intro_configuration.rst+14 0 modified
    @@ -85,6 +85,20 @@ different locations::
     Most users will not need to use this feature.  See :doc:`developing_plugins` for more details.
     
     
    +.. _allow_unsafe_lookups:
    +
    +allow_unsafe_lookups
    +====================
    +
    +.. versionadded:: 2.2.3, 2.3.1
    +
    +When enabled, this option allows lookup plugins (whether used in variables as `{{lookup('foo')}}` or as a loop as `with_foo`) to return data that is **not** marked "unsafe". By default, such data is marked as unsafe to prevent the templating engine from evaluating any jinja2 templating language, as this could represent a security risk.
    +
    +This option is provided to allow for backwards-compatibility, however users should first consider adding `allow_unsafe=True` to any lookups which may be expected to contain data which may be run through the templating engine later. For example::
    +
    +    {{lookup('pipe', '/path/to/some/command', allow_unsafe=True)}}
    +
    +
     .. _allow_world_readable_tmpfiles:
     
     allow_world_readable_tmpfiles
    
  • examples/ansible.cfg+6 0 modified
    @@ -265,6 +265,12 @@
     # set to 0 for unlimited (RAM may suffer!).
     #max_diff_size = 1048576
     
    +# When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
    +# a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain
    +# jinja2 templating language which will be run through the templating engine.
    +# ENABLING THIS COULD BE A SECURITY RISK
    +#allow_unsafe_lookups = False
    +
     [privilege_escalation]
     #become=True
     #become_method=sudo
    
  • lib/ansible/constants.py+1 0 modified
    @@ -191,6 +191,7 @@ def load_config_file():
     DEFAULT_INVENTORY_IGNORE  = get_config(p, DEFAULTS, 'inventory_ignore_extensions', 'ANSIBLE_INVENTORY_IGNORE', ["~", ".orig", ".bak", ".ini", ".cfg", ".retry", ".pyc", ".pyo"], islist=True)
     DEFAULT_VAR_COMPRESSION_LEVEL = get_config(p, DEFAULTS, 'var_compression_level', 'ANSIBLE_VAR_COMPRESSION_LEVEL', 0, integer=True)
     DEFAULT_INTERNAL_POLL_INTERVAL = get_config(p, DEFAULTS, 'internal_poll_interval', None, 0.001, floating=True)
    +DEFAULT_ALLOW_UNSAFE_LOOKUPS = get_config(p, DEFAULTS, 'allow_unsafe_lookups', None, False, boolean=True)
     ERROR_ON_MISSING_HANDLER  = get_config(p, DEFAULTS, 'error_on_missing_handler', 'ANSIBLE_ERROR_ON_MISSING_HANDLER', True, boolean=True)
     
     # static includes
    
  • lib/ansible/template/__init__.py+8 2 modified
    @@ -213,6 +213,9 @@ def __init__(self, loader, shared_loader_obj=None, variables=dict()):
                 loader=FileSystemLoader(self._basedir),
             )
     
    +        # the current rendering context under which the templar class is working
    +        self.cur_context = None
    +
             self.SINGLE_VAR = re.compile(r"^%s\s*(\w*)\s*%s$" % (self.environment.variable_start_string, self.environment.variable_end_string))
     
             self.block_start    = self.environment.block_start_string
    @@ -493,6 +496,7 @@ def _lookup(self, name, *args, **kwargs):
     
             if instance is not None:
                 wantlist = kwargs.pop('wantlist', False)
    +            allow_unsafe = kwargs.pop('allow_unsafe', C.DEFAULT_ALLOW_UNSAFE_LOOKUPS)
     
                 from ansible.utils.listify import listify_lookup_plugin_terms
                 loop_terms = listify_lookup_plugin_terms(terms=args, templar=self, loader=self._loader, fail_on_undefined=True, convert_bare=False)
    @@ -506,7 +510,7 @@ def _lookup(self, name, *args, **kwargs):
                         raise AnsibleError("An unhandled exception occurred while running the lookup plugin '%s'. Error was a %s, original message: %s" % (name, type(e), e))
                     ran = None
     
    -            if ran:
    +            if ran and not allow_unsafe:
                     from ansible.vars.unsafe_proxy import UnsafeProxy, wrap_var
                     if wantlist:
                         ran = wrap_var(ran)
    @@ -519,6 +523,8 @@ def _lookup(self, name, *args, **kwargs):
                             else:
                                 ran = wrap_var(ran)
     
    +                if self.cur_context:
    +                    self.cur_context.unsafe = True
                 return ran
             else:
                 raise AnsibleError("lookup plugin (%s) not found" % name)
    @@ -576,7 +582,7 @@ def do_template(self, data, preserve_trailing_newlines=True, escape_backslashes=
     
                 jvars = AnsibleJ2Vars(self, t.globals)
     
    -            new_context = t.new_context(jvars, shared=True)
    +            self.cur_context = new_context = t.new_context(jvars, shared=True)
                 rf = t.root_render_func(new_context)
     
                 try:
    
fd30f5328986

Fixing security issue with lookup returns not tainting the jinja2 environment

https://github.com/ansible/ansibleJames CammarataMay 8, 2017via ghsa
4 files changed · +43 2
  • docsite/rst/intro_configuration.rst+28 0 modified
    @@ -74,6 +74,34 @@ different locations::
     
     Most users will not need to use this feature.  See :doc:`developing_plugins` for more details.
     
    +
    +.. _allow_unsafe_lookups:
    +
    +allow_unsafe_lookups
    +====================
    +
    +.. versionadded:: 2.2.3, 2.3.1
    +
    +When enabled, this option allows lookup plugins (whether used in variables as `{{lookup('foo')}}` or as a loop as `with_foo`) to return data that is **not** marked "unsafe". By default, such data is marked as unsafe to prevent the templating engine from evaluating any jinja2 templating language, as this could represent a security risk.
    +
    +This option is provided to allow for backwards-compatibility, however users should first consider adding `allow_unsafe=True` to any lookups which may be expected to contain data which may be run through the templating engine later. For example::
    +
    +    {{lookup('pipe', '/path/to/some/command', allow_unsafe=True)}}
    +
    +
    +.. _allow_world_readable_tmpfiles:
    +
    +allow_world_readable_tmpfiles
    +=============================
    +
    +.. versionadded:: 2.1
    +This makes the temporary files created on the machine to be world readable and will issue a warning instead of failing the task. 
    +
    +It is useful when becoming an unprivileged user::
    +
    +  allow_world_readable_tmpfiles=True
    +
    +
     .. _ansible_managed:
     
     ansible_managed
    
  • examples/ansible.cfg+6 0 modified
    @@ -252,6 +252,12 @@
     # set to 0 for unlimited (RAM may suffer!).
     #max_diff_size = 1048576
     
    +# When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
    +# a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain
    +# jinja2 templating language which will be run through the templating engine.
    +# ENABLING THIS COULD BE A SECURITY RISK
    +#allow_unsafe_lookups = False
    +
     [privilege_escalation]
     #become=True
     #become_method=sudo
    
  • lib/ansible/constants.py+1 0 modified
    @@ -182,6 +182,7 @@ def load_config_file():
     DEFAULT_FORCE_HANDLERS    = get_config(p, DEFAULTS, 'force_handlers', 'ANSIBLE_FORCE_HANDLERS', False, boolean=True)
     DEFAULT_INVENTORY_IGNORE  = get_config(p, DEFAULTS, 'inventory_ignore_extensions', 'ANSIBLE_INVENTORY_IGNORE', ["~", ".orig", ".bak", ".ini", ".cfg", ".retry", ".pyc", ".pyo"], islist=True)
     DEFAULT_VAR_COMPRESSION_LEVEL = get_config(p, DEFAULTS, 'var_compression_level', 'ANSIBLE_VAR_COMPRESSION_LEVEL', 0, integer=True)
    +DEFAULT_ALLOW_UNSAFE_LOOKUPS = get_config(p, DEFAULTS, 'allow_unsafe_lookups', None, False, boolean=True)
     
     # static includes
     DEFAULT_TASK_INCLUDES_STATIC    = get_config(p, DEFAULTS, 'task_includes_static', 'ANSIBLE_TASK_INCLUDES_STATIC', False, boolean=True)
    
  • lib/ansible/template/__init__.py+8 2 modified
    @@ -213,6 +213,9 @@ def __init__(self, loader, shared_loader_obj=None, variables=dict()):
                 loader=FileSystemLoader(self._basedir),
             )
     
    +        # the current rendering context under which the templar class is working
    +        self.cur_context = None
    +
             self.SINGLE_VAR = re.compile(r"^%s\s*(\w*)\s*%s$" % (self.environment.variable_start_string, self.environment.variable_end_string))
     
             self.block_start    = self.environment.block_start_string
    @@ -482,6 +485,7 @@ def _lookup(self, name, *args, **kwargs):
     
             if instance is not None:
                 wantlist = kwargs.pop('wantlist', False)
    +            allow_unsafe = kwargs.pop('allow_unsafe', C.DEFAULT_ALLOW_UNSAFE_LOOKUPS)
     
                 from ansible.utils.listify import listify_lookup_plugin_terms
                 loop_terms = listify_lookup_plugin_terms(terms=args, templar=self, loader=self._loader, fail_on_undefined=True, convert_bare=False)
    @@ -495,7 +499,7 @@ def _lookup(self, name, *args, **kwargs):
                         raise AnsibleError("An unhandled exception occurred while running the lookup plugin '%s'. Error was a %s, original message: %s" % (name, type(e), e))
                     ran = None
     
    -            if ran:
    +            if ran and not allow_unsafe:
                     from ansible.vars.unsafe_proxy import UnsafeProxy, wrap_var
                     if wantlist:
                         ran = wrap_var(ran)
    @@ -508,6 +512,8 @@ def _lookup(self, name, *args, **kwargs):
                             else:
                                 ran = wrap_var(ran)
     
    +                if self.cur_context:
    +                    self.cur_context.unsafe = True
                 return ran
             else:
                 raise AnsibleError("lookup plugin (%s) not found" % name)
    @@ -566,7 +572,7 @@ def _do_template(self, data, preserve_trailing_newlines=True, escape_backslashes
     
                 jvars = AnsibleJ2Vars(self, t.globals)
     
    -            new_context = t.new_context(jvars, shared=True)
    +            self.cur_context = new_context = t.new_context(jvars, shared=True)
                 rf = t.root_render_func(new_context)
     
                 try:
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

19

News mentions

0

No linked articles in our index yet.