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
10.3 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 20:37

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.90 PyYAML's base64 decoding for !!binary scalars, with a Python 2/3 compatibility fallback.
    Reasoning

    This is PyYAML's standard binary-scalar constructor, which decodes the !!binary tag's base64 payload. The snippet shows a compatibility shim choosing decodebytes or decodestring, with no network access, execution, or hidden payload. The pass flagged decompression, but this is ordinary data decoding.

  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 module import for the python/name tag, which loads a module named in the YAML document.
    Reasoning

    The `__import__` call sits inside PyYAML's python/name constructor, which loads a module named by the YAML tag and turns ImportError into a ConstructorError. The module name comes from the document being loaded, so this is a known PyYAML feature with an unsafe-loader risk, not an obfuscated dropper. The critical severity overstates it for this library.

  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 module import for the python/object tag, resolving a module named in the YAML tag.
    Reasoning

    This is the companion `__import__` in PyYAML's python/object constructor, which resolves the object's module from the YAML tag. It is the same legitimate, though unsafe-by-design, loader behavior as the other constructor finding, and the snippet shows no obfuscation.

  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
    likely benign LLM, confidence 0.80 Test helper that executes code strings from test fixtures and returns a global value.
    Reasoning

    The `exec(code)` call is in a test helper that runs YAML test fixture code, which is typical for a YAML library's legacy test suite. It is not in the shipped runtime path and shows no encoding or concealment.

  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):
    likely benign LLM, confidence 0.80 Test helper that evaluates expression strings used in constructor tests.
    Reasoning

    The `eval(expression)` call is a small test helper for evaluating expressions in YAML test data. It is consistent with a parser test suite and carries no concealment.

  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:
    likely benign LLM, confidence 0.80 Error-handling test that executes a code string and catches YAML errors.
    Reasoning

    The `exec(code)` call runs test input inside a try block that catches YAMLError, which is a standard error-reporting check in a parser test. It is confined to the test suite.

  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):
    likely benign LLM, confidence 0.80 Test helper that evaluates expression strings for multi-constructor tests.
    Reasoning

    This is the same `eval` test helper pattern as in the constructor tests, used to build test objects. The file is a legacy test module for multi-constructors and does not touch production code.

  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
    likely benign LLM, confidence 0.80 Test that executes a fixture file to build recursive structures and compare results.
    Reasoning

    The `exec` call loads a recursive-structure fixture file into a context dictionary, which is a common test pattern for checking YAML recursion. The fixture is a local test file and the snippet shows no hidden payload.

  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:
    likely benign LLM, confidence 0.80 Test that evaluates a structure fixture file to compare expected node trees.
    Reasoning

    The `eval(file.read())` call loads a structure fixture from a test data file to compare parsed nodes. It is test scaffolding, not runtime behavior, and the file is a known local fixture.

  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,   \
    likely benign LLM, confidence 0.85 Test registration helper that adds test functions to module globals.
    Reasoning

    The `globals()` access registers a test function in the module namespace and checks for name collisions first. This is a common test-discovery idiom with no evidence of hiding or dynamic dispatch of malicious logic.

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/yaml/pyyaml pyyaml && cd pyyaml
git checkout 6.0.3
disclude scan --severity info --diff 6.0.2 .