python-3.x - 当默认加载程序已经变得更加安全时,为什么PyYAML 5.1会引发YAMLLoadWarning?

标签 python-3.x security yaml warnings pyyaml

这是我的代码:

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只有三种可用的选择:受限的BaseLoaderSafeLoader和不安全的Loader。尽管默认值是不安全的,但就像我们从文档中看到的那样:


自5月首次发布以来,PyYAML的load函数一直不安全。
2006。它始终以粗体显示:PyYAMLDocumentation。
PyYAML一直提供safe_load函数,该函数可以加载
没有漏洞利用的YAML。


但是仍然有很多资源,教程更喜欢直接使用yaml.load(f),因此用户(尤其是新用户)正在隐式选择默认的Loader类。



由于PyYAML版本5.1yaml.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)UnsafeLoaderLoader相同)

不安全但是拥有全力。

关于python-3.x - 当默认加载程序已经变得更加安全时,为什么PyYAML 5.1会引发YAMLLoadWarning?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55677397/

相关文章:

python-3.x - 如何改进决策树回归器中的负 R 平方

php - parse_ini_file() 出于安全原因已被禁用 - 替代方案?

security - Hacking : how do I find security holes in my own web application? 我在保护它方面做得很好吗?

java - 如何在 Windows 中安全地存储临时文件,尤其是在安全入侵防护应用程序阻止 TEMP 目录的情况下

python - 从列表中删除重复项的时间和空间复杂度

csv - 07002 [Microsoft][ODBC SQL Server 驱动程序]COUNT 字段不正确或语法错误

python - matplotlib 如何知道要在此代码中显示什么?

python - 使用 python 在给定输入参数的文件中追加一行

yaml - ElasticBeanstalk CFT 命名空间中的变量

ruby-on-rails - 从 i18n YAML 文件获取字符串?