Skip to content

[Bug]: Alias Cycles Produce Self-Referential Structures That Break Consumers #896

@tylzh97

Description

@tylzh97

Summary

SafeLoader permits alias-based cycles (lists or !!omap) that create self-referential objects; downstream traversal without cycle detection hits infinite recursion.

poc:

  • Alias
     import yaml
     data = yaml.safe_load("- &loop\n  - *loop")
     def walk(obj):
         if isinstance(obj, list):
             for item in obj: walk(item)
    
     walk(data)
  • OMAP
     import yaml
     data = yaml.safe_load("!!omap &loop\n- key: *loop")
     def walk(obj):
         if isinstance(obj, (list, tuple)):
             for item in obj: walk(item)
    
     walk(data)

Traceback:

$ uv run python 
Python 3.10.18 (main, Sep  2 2025, 14:19:37) [Clang 20.1.4 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import yaml
>>> data = yaml.safe_load("- &loop\n  - *loop")
>>> def walk(obj):
...     if isinstance(obj, (list, tuple)):
...         for item in obj: walk(item)
... 
>>> walk(data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in walk
  File "<stdin>", line 3, in walk
  File "<stdin>", line 3, in walk
  [Previous line repeated 994 more times]
  File "<stdin>", line 2, in walk
RecursionError: maximum recursion depth exceeded in __instancecheck__
>>> 

Suggested Fix

  • Detect alias cycles during construction and fail fast.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions