Skip to content

Commit

Permalink
Fix the YAML.load_file decorator to be as strict as regular YAML.lo…
Browse files Browse the repository at this point in the history
…ad_file

Fix: #434

Our strictness was based on the incorrect assumption that all extra types
would use a tag, which is incorrect as `Time` and `Date` objects can be
expressed in regular YAML syntax without the use of `!ruby/object`.
  • Loading branch information
byroot committed Jan 22, 2023
1 parent a79a163 commit 566dd18
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
@@ -1,6 +1,9 @@
# Unreleased

* Use `RbConfig::CONFIG["rubylibdir"]` instead of `RbConfig::CONFIG["libdir"]` to check for stdlib files. See #431.
* Fix the cached version of `YAML.load_file` being slightly more permissive than the default `Psych` one. See #434.
`Date` and `Time` values are now properly rejected, as well as aliases.
If this causes a regression in your application, it is recommended to load *trusted* YAML files with `YAML.unsafe_load_file`.

# 1.15.0

Expand Down
7 changes: 5 additions & 2 deletions lib/bootsnap/compile_cache/yaml.rb
Expand Up @@ -65,7 +65,7 @@ def init!
end

unless const_defined?(:NoTagsVisitor)
visitor = Class.new(Psych::Visitors::ToRuby) do
visitor = Class.new(Psych::Visitors::NoAliasRuby) do
def visit(target)
if target.tag
raise UnsupportedTags, "YAML tags are not supported: #{target.tag}"
Expand Down Expand Up @@ -129,7 +129,10 @@ def strict_load(payload)
ast = ::YAML.parse(payload)
return ast unless ast

NoTagsVisitor.create.visit(ast)
loader = ::Psych::ClassLoader::Restricted.new(["Symbol"], [])
scanner = ::Psych::ScalarScanner.new(loader)

NoTagsVisitor.new(scanner, loader).visit(ast)
end
end

Expand Down
32 changes: 32 additions & 0 deletions test/compile_cache/yaml_test.rb
Expand Up @@ -37,6 +37,38 @@ def test_yaml_strict_load
assert_equal expected, document
end

def test_strict_load_reject_dates
error = assert_raises Psych::DisallowedClass do
::Bootsnap::CompileCache::YAML.strict_load(<<~YAML)
---
:foo: 2023-01-20
YAML
end
assert_includes error.message, "Date"
end

def test_strict_load_reject_times
error = assert_raises Psych::DisallowedClass do
::Bootsnap::CompileCache::YAML.strict_load(<<~YAML)
---
:foo: 2023-01-20 13:18:31.083375000 -05:00
YAML
end
assert_includes error.message, "Time"
end

def test_strict_load_reject_aliases
assert_raises Psych::BadAlias do
::Bootsnap::CompileCache::YAML.strict_load(<<~YAML)
---
foo: &foo
a: b
bar:
<<: *foo
YAML
end
end

def test_yaml_tags
error = assert_raises Bootsnap::CompileCache::YAML::UnsupportedTags do
::Bootsnap::CompileCache::YAML.strict_load("!many Boolean")
Expand Down

0 comments on commit 566dd18

Please sign in to comment.