这是我的代码:
import yaml
yaml.load('foo')
此代码导致PyYAML(5.1)出现以下警告。
$ pip install pyyaml
$ python3 foo.py
foo.py:2: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
yaml.load('foo')
因此,我访问了https://msg.pyyaml.org/load以了解这是怎么回事,但我不明白此警告的必要性。
首先,文档说,
UnsafeLoader
(为了向后兼容,也称为Loader
)不受信任的数据输入很容易利用的原始Loader代码。
好的,那很有道理。在较早的版本中,原始加载程序不安全。此外,它说,
FullLoader
加载完整的YAML语言。避免执行任意代码。当前(PyYAML 5.1)是
yaml.load(input)
调用的默认加载程序(发出警告后)。因此,当前版本使用
FullLoader
并非不安全。在文档中再次确认。通过禁止默认加载程序(
FullLoader
)执行任意功能,还使加载功能更加安全。如果当前使用
FullLoader
的版本并非不安全,那么为什么我们完全需要YAMLLoadWarning
?
最佳答案
我认为此警告更像是一个通知和指导,旨在使用户知道将来的PyYAML最佳做法是什么。回想一下:显式优于隐式。
在版本5.1(例如4.1)之前,yaml.load
api默认使用Loader=Loader
:
def load(stream, Loader=Loader):
"""
Parse the first YAML document in a stream
and produce the corresponding Python object.
"""
loader = Loader(stream)
try:
return loader.get_single_data()
finally:
loader.dispose()
def safe_load(stream):
"""
Parse the first YAML document in a stream
and produce the corresponding Python object.
Resolve only basic YAML tags.
"""
return load(stream, SafeLoader)
那时,
Loader
class只有三种可用的选择:受限的BaseLoader
,SafeLoader
和不安全的Loader
。尽管默认值是不安全的,但就像我们从文档中看到的那样:自5月首次发布以来,PyYAML的
load
函数一直不安全。2006。它始终以粗体显示:PyYAMLDocumentation。
PyYAML一直提供
safe_load
函数,该函数可以加载没有漏洞利用的YAML。
但是仍然有很多资源,教程更喜欢直接使用
yaml.load(f)
,因此用户(尤其是新用户)正在隐式选择默认的Loader类。由于PyYAML版本5.1,
yaml.load
api更改为更加明确:def load(stream, Loader=None):
"""
Parse the first YAML document in a stream
and produce the corresponding Python object.
"""
if Loader is None:
load_warning('load')
Loader = FullLoader
loader = Loader(stream)
try:
return loader.get_single_data()
finally:
loader.dispose()
def safe_load(stream):
"""
Parse the first YAML document in a stream
and produce the corresponding Python object.
Resolve only basic YAML tags. This is known
to be safe for untrusted input.
"""
return load(stream, SafeLoader)
并将新的
FullLoader
添加到Loader
classes中。作为用户,我们还应该意识到这些变化,并更明确地使用yaml.load
:yaml.load(stream, yaml.SafeLoader)
推荐用于不受信任的输入。限制:加载YAML语言的子集。
yaml.load(stream, yaml.FullLoader)
获得更多值得信赖的输入。还有一点限制:避免执行任意代码。
yaml.load(stream, yaml.Loader)
(UnsafeLoader
与Loader
相同)不安全但是拥有全力。
关于python-3.x - 当默认加载程序已经变得更加安全时,为什么PyYAML 5.1会引发YAMLLoadWarning?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55677397/