在 ruamel.yaml 中使用默认负载是否安全
Is it safe to use the default load in ruamel.yaml
我可以使用 ruamel.yaml 加载和转储带有标签的 YAML 文件,并且标签被保留。
如果我让我的客户编辑 YAML 文档,他们会因为任意 python 模块代码执行而能够利用 YAML 漏洞吗?据我了解,ruamel.yaml 派生自 PyYAML,根据其文档,该 PyYAML 具有此类漏洞。
根据你的问题,我推断你正在 YAML()
实例上使用 .load()
方法,如:
import ruamel.yaml
yaml = ruamel.yaml.YAML()
data = yaml.load(some_path)
而不是旧的 PyYAML load
兼容函数(它不能处理未知标签,而且可能不安全)。简短的回答是,是的,这是安全的,因为在不调用任何标签相关代码的情况下不会对标签进行解释,标签只是被分配(作为字符串)给已知类型(CommentedMap
、CommentedSeq
、TaggedScalar
分别用于映射、序列和标量)。
PyYAML 中的漏洞来自其 Constructor
,即不安全 Loader
的一部分。这是 PyYAML 最长的默认设置,大多数人使用它,即使他们本可以使用安全加载器,因为他们没有使用任何标签(或者可以根据 SafeLoader/Constructor
注册他们需要的标签)。不安全 Constructor
是 SafeConstructor
的子类,不安全的原因是 multi-methods 注册用于解释 python/{name,module,object,apply,new):....
标签,本质上是动态解释这些标签以加载模块和 运行代码(即执行functions/methods/instantiate类)。
ruamel.yaml
背后的最初想法是 RoundTripConstructor
, which is also a subclass of the SafeConstructor
。您曾经使用现已弃用的 round_trip_load
函数来获取它,而现在在使用 YAML(typ='rt')
之后通过 .load()
方法获取它,这也是没有 [=30] 的 YAML()
实例的默认设置=] 参数。 RoundTripConstructor
不 注册任何标签或有任何代码解释标签超出 SafeConstructor
使用的正常标签。
只有旧的 PyYAML load
和 ruamel.yaml 使用 typ='unsafe'
可以通过 !!python/..
标签执行代码在篡改的 YAML 输入上执行任意 Python 代码.
当您使用 typ='rt'
时,即使未注册标签,节点上的标签也会保留。这是可能的,因为在处理节点时(在 round-trip 模式下),这些标记将作为字符串分配给标记节点(映射、序列或标量,标记 [ 除外)的构造类型上的属性。 =37=]).并且在转储这些类型时,如果它们有标签,它会将 re-inserted 放入表示处理代码中。 标签在任何时候都不会被评估、用于导入代码等。
我可以使用 ruamel.yaml 加载和转储带有标签的 YAML 文件,并且标签被保留。
如果我让我的客户编辑 YAML 文档,他们会因为任意 python 模块代码执行而能够利用 YAML 漏洞吗?据我了解,ruamel.yaml 派生自 PyYAML,根据其文档,该 PyYAML 具有此类漏洞。
根据你的问题,我推断你正在 YAML()
实例上使用 .load()
方法,如:
import ruamel.yaml
yaml = ruamel.yaml.YAML()
data = yaml.load(some_path)
而不是旧的 PyYAML load
兼容函数(它不能处理未知标签,而且可能不安全)。简短的回答是,是的,这是安全的,因为在不调用任何标签相关代码的情况下不会对标签进行解释,标签只是被分配(作为字符串)给已知类型(CommentedMap
、CommentedSeq
、TaggedScalar
分别用于映射、序列和标量)。
PyYAML 中的漏洞来自其 Constructor
,即不安全 Loader
的一部分。这是 PyYAML 最长的默认设置,大多数人使用它,即使他们本可以使用安全加载器,因为他们没有使用任何标签(或者可以根据 SafeLoader/Constructor
注册他们需要的标签)。不安全 Constructor
是 SafeConstructor
的子类,不安全的原因是 multi-methods 注册用于解释 python/{name,module,object,apply,new):....
标签,本质上是动态解释这些标签以加载模块和 运行代码(即执行functions/methods/instantiate类)。
ruamel.yaml
背后的最初想法是 RoundTripConstructor
, which is also a subclass of the SafeConstructor
。您曾经使用现已弃用的 round_trip_load
函数来获取它,而现在在使用 YAML(typ='rt')
之后通过 .load()
方法获取它,这也是没有 [=30] 的 YAML()
实例的默认设置=] 参数。 RoundTripConstructor
不 注册任何标签或有任何代码解释标签超出 SafeConstructor
使用的正常标签。
只有旧的 PyYAML load
和 ruamel.yaml 使用 typ='unsafe'
可以通过 !!python/..
标签执行代码在篡改的 YAML 输入上执行任意 Python 代码.
当您使用 typ='rt'
时,即使未注册标签,节点上的标签也会保留。这是可能的,因为在处理节点时(在 round-trip 模式下),这些标记将作为字符串分配给标记节点(映射、序列或标量,标记 [ 除外)的构造类型上的属性。 =37=]).并且在转储这些类型时,如果它们有标签,它会将 re-inserted 放入表示处理代码中。 标签在任何时候都不会被评估、用于导入代码等。