在 Psych 4 中使用 YAML/Store 加载不安全的 YAML

Dan*_*nyB 3 ruby yaml

Ruby 的 YAML 库 (Psych 4) 的最新更改会导致“不安全”YAML 在包含别名或尝试实例化未指定的类时失败。这在多个地方都有讨论,例如StackOverflow 问题

我试图弄清楚如何告诉衍生yaml/store库允许加载不安全的 YAML,或者向它提供允许的类列表。

据我所知,该文档很少,阅读后,这是我能想到的唯一合乎逻辑的尝试:

require 'date'
require 'yaml/store'

# 1. These options work perfectly with YAML.load_file, but not with YAML::Store
# 2. These options are not needed in Psych < 4.0
yaml_opts = { aliases: true, permitted_classes: [Time, Date, Symbol] }

store = YAML::Store.new 'log.yml', yaml_opts
data = store.transaction { store[:entries] }
p data
Run Code Online (Sandbox Code Playgroud)

使用此 YAML 文件:

# log.yml
:entries:
- :timestamp: 2018-07-09 00:00:00.000000000 +03:00
  :action: Comment
  :comment: Started logging
Run Code Online (Sandbox Code Playgroud)

这在 Psych 4 中失败,在 Psych 3 中成功。

# Gemfile
source "https://rubygems.org"
gem 'psych', '>= 4.0'    # fail
# gem 'psych', '< 4.0'   # pass
Run Code Online (Sandbox Code Playgroud)

作为一个相关的轶事,文档中演示的示例在尝试使用以下命令加载时也会失败store.transaction { store["people"] }

Dan*_*nyB 10

虽然这不是正确的做法,但在有更好的答案之前,我发现添加以下代码可以解决问题。

\n
module YAML\n  class << self\n    alias_method :load, :unsafe_load\n  end\nend\n
Run Code Online (Sandbox Code Playgroud)\n

这只是将底层YAML::load方法恢复为其 3.x 行为,unsafe_load而不是safe_load.

\n

如果我的 YAML 来自受信任的来源(100% 的用例),我看不到新的 Psych 4 行为有任何好处,并且觉得恢复它是可以的(尽管很尴尬)。

\n

相关源代码参考是3.3.2 \xe2\x86\x92 4.0.0 diff

\n