PyPI / pyyaml / 6.0.3

pyyaml 6.0.3

Source
https://github.com/yaml/pyyaml
Tag scanned
6.0.3
Compared with
6.0.2 (0 signals introduced since)
Files
51 scanned, 585 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 10 info
Scan time
9.1 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 10 of 10 warn and critical signals; 10 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-14 18:10

Signals

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

  1. info warn → info by review decoder-decompress-payload lib/yaml/constructor.py:303:24

    file imports decoder module(s) base64, binascii and calls `.decompress()` — embedded payload decompressed at runtime (ast pass, confidence 0.75)

                if hasattr(base64, 'decodebytes'):
                    return base64.decodebytes(value)
                else:
                    return base64.decodestring(value)
    likely benign LLM, confidence 0.93 PyYAML's binary-tag constructor, decoding base64 values.
    Reasoning

    This is PyYAML's standard !!binary constructor, which decodes base64 data embedded in YAML documents. The base64 decode is the documented purpose of the code, not a hidden payload, and the hasattr fallback is ordinary Python 2/3 compatibility.

  2. info critical → info by review dynamic-import lib/yaml/constructor.py:531:17

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

                try:
                    __import__(name)
                except ImportError as exc:
                    raise ConstructorError("while constructing a Python module", mark,
    likely benign LLM, confidence 0.85 PyYAML's python/module tag constructor, which calls __import__ on a tag-supplied name.
    Reasoning

    This is PyYAML's python/module constructor, which imports a module named in the YAML tag. It is a known unsafe-by-design feature of full-loader PyYAML, but it is the library's expected behavior and not obfuscation or a covert dropper. The risk is in using unsafe loaders on untrusted input, not in the code itself.

  3. info critical → info by review dynamic-import lib/yaml/constructor.py:551:17

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

                try:
                    __import__(module_name)
                except ImportError as exc:
                    raise ConstructorError("while constructing a Python object", mark,
    likely benign LLM, confidence 0.85 PyYAML's python/object tag constructor, which calls __import__ on a tag-supplied module name.
    Reasoning

    This is PyYAML's python/object constructor, which imports a module named in the tag before resolving the object. It matches the upstream library and is a documented unsafe-loader feature, not hidden malicious logic.

  4. info warn → info by review dynamic-execution tests/legacy_tests/test_constructor.py:13:5

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

        global value
        exec(code)
        return value
    dismissed LLM, confidence 0.92 Test helper that execs fixture code strings to check constructor output.
    Reasoning

    This is PyYAML's legacy test harness. The exec(code) runs test-fixture source strings to check constructor behavior. The input is controlled by the test suite, so it is an ordinary test pattern.

  5. info warn → info by review dynamic-execution tests/legacy_tests/test_constructor.py:235:12

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

    def _load_code(expression):
        return eval(expression)
    
    def _serialize_value(data):
    dismissed LLM, confidence 0.92 Test helper that evals test expression strings for comparison.
    Reasoning

    This is a test helper that evals test expressions to compare against YAML-loaded values. The input comes from the test suite's own fixtures, and nothing in the snippet indicates an attacker-controlled source.

  6. info warn → info by review dynamic-execution tests/legacy_tests/test_errors.py:59:9

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

            from io import StringIO
            exec(code)
        except yaml.YAMLError as exc:
            if verbose:
    dismissed LLM, confidence 0.92 Error-test helper that execs a fixture string to provoke YAML errors.
    Reasoning

    This is an error-handling test in PyYAML's suite that execs a fixture code string to trigger a YAML error. It is a standard test pattern with no hidden behavior.

  7. info warn → info by review dynamic-execution tests/legacy_tests/test_multi_constructor.py:6:12

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

    def _load_code(expression):
        return eval(expression)
    
    def myconstructor1(constructor, tag, node):
    dismissed LLM, confidence 0.92 Test helper that evals expression fixtures for multi-constructor tests.
    Reasoning

    This is the same eval-based test helper for expression fixtures used in PyYAML's multi-constructor tests. The input is fixture-controlled.

  8. info warn → info by review dynamic-execution tests/legacy_tests/test_recursive.py:28:9

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

        with open(recursive_filename, 'rb') as file:
            exec(file.read(), context)
        value1 = context['value']
        output1 = None
    dismissed LLM, confidence 0.92 Test that execs a bundled fixture file to build recursive test data.
    Reasoning

    This recursive-structure test execs a bundled test data file into a context dict and reads back the expected value. The file is a repository fixture, so this is an ordinary test pattern.

  9. info warn → info by review dynamic-execution tests/legacy_tests/test_structure.py:38:18

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

        with open(structure_filename, 'r') as file:
            nodes2 = eval(file.read())
        try:
            with open(data_filename, 'rb') as file:
    dismissed LLM, confidence 0.90 Test that evals a bundled structure fixture to compare node shapes.
    Reasoning

    This test evals a bundled structure fixture file to compare parsed node structure. The source is a repository test file, not untrusted input, so the eval is a normal test technique here.

  10. info warn → info by review dynamic-attribute tests/legacy_tests/test_yaml_ext.py:284:9

    reach-by-name through `globals` (ast pass, confidence 0.60)

            assert function.__name__ not in globals()
            globals()[function.__name__] = function
    
    import test_tokens, test_structure, test_errors, test_resolver, test_constructor,   \
    dismissed LLM, confidence 0.90 Test runner that registers test functions in the module globals() namespace.
    Reasoning

    The test runner checks for and registers test functions by name in globals(), a common idiom in ad-hoc test harnesses. It affects only the test module's own namespace and has no supply-chain significance.

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.0.0
git clone https://github.com/yaml/pyyaml pyyaml && cd pyyaml
git checkout 6.0.3
disclude scan --severity info --diff 6.0.2 .