PyPI / jinja2 / 3.1.6

jinja2 3.1.6

Source
https://github.com/pallets/jinja
Tag scanned
3.1.6
Compared with
3.1.5 (0 signals introduced since)
Files
89 scanned, 15 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 12 info
Scan time
8.8 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 10 of 10 warn and critical signals; 10 demoted to info.
Disclude version
4.1.0
Scanned (UTC)
2026-10-21 22:04

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. info warn → info by review dynamic-execution docs/api.rst:817:1

    [markup prose] `eval` called on a string literal (ast pass, confidence 0.85)

    eval context object itself.
    dismissed LLM, confidence 0.97 A documentation sentence mentioning the word 'eval' in prose.
    Reasoning

    The snippet is prose in reStructuredText documentation ('eval context object itself.'), not a call to eval. The finding is a false match on the word in text.

  2. info unicode-mixed-script src/jinja2/_identifier.py:5:27

    identifier `ׇֽֿׁׂׅׄؐ` mixes scripts: Hebrew + Arabic (in string/comment) (raw pass, confidence 0.40)

        r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ
  3. info unicode-mixed-script src/jinja2/_identifier.py:5:70

    identifier `ܑۭܰ` mixes scripts: Arabic + Other (in string/comment) (raw pass, confidence 0.40)

    �ׇׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூ… (340 bytes total)
  4. info critical → info by review unicode-invisible src/jinja2/_identifier.py:5:1101

    4 invisible tag characters on this line (possible encoded payload) (raw pass, confidence 0.99)

    ��ꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ⟨U+FE00⟩-⟨U+FE0F⟩︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𐴤-𐽆𐴧-𐽐𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑄴𑅅𑅆𑅳𑆀-𑆂𑆳-𑇀𑇉-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌻𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗… (339 bytes total)
    likely benign LLM, confidence 0.85 A long line of Unicode characters defining the valid identifier character set for the template engine.
    Reasoning

    This file is Jinja2's generated Unicode identifier table, a regex character class of ID_Start/ID_Continue ranges. Invisible and variation-selector code points are expected in such a table. The 'encoded payload' reading does not fit a regex character class.

  5. info warn → info by review dynamic-execution src/jinja2/bccache.py:79:25

    `marshal.load` deserializes Python bytecode from bytes — code-object sink (ast pass, confidence 0.75)

            try:
                self.code = marshal.load(f)
            except (EOFError, ValueError, TypeError):
                self.reset()
    likely benign LLM, confidence 0.80 Loads cached compiled template bytecode from a file in the bytecode cache.
    Reasoning

    marshal.load on a bytecode cache file is Jinja2's documented bytecode cache feature. It is a real code-object sink, so the risk is that an attacker who can write the cache directory could run code. That is a known trust-boundary property, not hidden malicious intent.

  6. info critical → info by review dynamic-execution src/jinja2/debug.py:105:22

    `compile` called on a constructed string (ast pass, confidence 0.80)

        # Raise an exception at the correct line number.
        code: CodeType = compile(
            "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec"
        )
    likely benign LLM, confidence 0.90 Builds a code object that raises an exception at the template line for traceback rewriting.
    Reasoning

    This compiles a constructed string that raises an exception at a chosen line number, to rewrite tracebacks for template errors. The string is built from integers and a fixed name, so it is a legitimate debugging technique.

  7. info warn → info by review dynamic-execution src/jinja2/debug.py:145:9

    `exec` called on a non-literal expression (ast pass, confidence 0.70)

        try:
            exec(code, globals, locals)
        except BaseException:
            return sys.exc_info()[2].tb_next  # type: ignore
    likely benign LLM, confidence 0.85 Executes the generated template code to produce a traceback frame.
    Reasoning

    exec runs compiled template code during traceback rewriting, with the code produced by the template compiler. This is the expected use in this debugging module.

  8. info warn → info by review dynamic-execution src/jinja2/environment.py:709:16

    `compile` called on a non-literal expression (ast pass, confidence 0.70)

            """
            return compile(source, filename, "exec")
    
        @typing.overload
    likely benign LLM, confidence 0.90 Compiles generated template source into a Python code object.
    Reasoning

    This is the core template compile step, turning template source into a code object. Compiling template source is the purpose of the engine.

  9. info warn → info by review dynamic-execution src/jinja2/environment.py:1228:9

    `exec` called on a non-literal expression (ast pass, confidence 0.70)

            namespace = {"environment": environment, "__file__": code.co_filename}
            exec(code, namespace)
            rv = cls._from_namespace(environment, namespace, globals)
            rv._uptodate = uptodate
    likely benign LLM, confidence 0.85 Executes compiled template code to create the template module namespace.
    Reasoning

    This executes a compiled template code object in a namespace when loading a template from bytecode or source. It is the normal template loading path.

  10. info critical → info by review dynamic-import src/jinja2/loaders.py:680:23

    `__import__` called on a non-literal expression (ast pass, confidence 0.70)

                try:
                    mod = __import__(module, None, None, ["root"])
                except ImportError as e:
                    raise TemplateNotFound(name) from e
    likely benign LLM, confidence 0.90 Dynamically imports the package named in PackageLoader to locate templates.
    Reasoning

    This imports a package module by name to load templates through PackageLoader. The module name comes from the loader's configuration by the developer, not from untrusted input.

  11. info critical → info by review dynamic-import src/jinja2/utils.py:157:20

    `__import__` called on a non-literal expression (ast pass, confidence 0.70)

            else:
                return __import__(import_name)
            return getattr(__import__(module, None, None, [obj]), obj)
        except (ImportError, AttributeError):
    likely benign LLM, confidence 0.90 Dynamically imports a module or attribute from a dotted import name.
    Reasoning

    This is the import_string helper, which imports a dotted name supplied by the developer. Dynamic import is its purpose, and it is a documented utility.

  12. info critical → info by review dynamic-import src/jinja2/utils.py:158:24

    `__import__` called on a non-literal expression (ast pass, confidence 0.70)

                return __import__(import_name)
            return getattr(__import__(module, None, None, [obj]), obj)
        except (ImportError, AttributeError):
            if not silent:
    likely benign LLM, confidence 0.90 Fallback dynamic import resolving an attribute from a dotted import name.
    Reasoning

    This is the same import_string helper's fallback path for resolving an attribute from a dotted name. It is a legitimate utility, with the same reasoning as the finding above.

Reproduce This Scan

Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.1.0
git clone https://github.com/pallets/jinja jinja && cd jinja
git checkout 3.1.6
disclude scan --severity info --diff 3.1.5 .