Skip to content

Commit

Permalink
Parse YAML safely
Browse files Browse the repository at this point in the history
An issue from June 2014,
lostisland#92, raises
the risks of the current `FaradayMiddleware::ParseYaml` middleware
which uses `YAML.load`. This method is very unsafe and exposes you
to remote code execution - see
ruby/psych#119 for discussion.

At the time, @mislav decided not to make this change to avoid
messing with backwards compatability.

I would suggest that we should revisit this decision - the risks
of this are very high, very few people are using this middleware
most likely, and it doesn't seem unreasonable to break this
as long as we are clear on the change in the changelog.

This does that by installing the `safe_yaml` gem, which is
compatible with all Ruby versions we support.
  • Loading branch information
Tim Rogers authored and petems committed Jul 3, 2017
1 parent e754e27 commit f21384b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
1 change: 1 addition & 0 deletions faraday_middleware.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Gem::Specification.new do |spec|
spec.licenses = ['MIT']

spec.add_dependency 'faraday', ['>= 0.7.4', '< 1.0']
spec.add_dependency 'safe_yaml'

spec.files = `git ls-files -z lib LICENSE.md README.md`.split("\0")
end
26 changes: 16 additions & 10 deletions lib/faraday_middleware/response/parse_yaml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,33 @@
module FaradayMiddleware
# Public: Parse response bodies as YAML.
#
# Warning: this uses `YAML.load()` by default and as such is not safe against
# code injection or DoS attacks. If you're loading resources from an
# untrusted host or over HTTP, you should subclass this middleware and
# redefine it to use `safe_load()` if you're using a Psych version that
# supports it:
# Warning: This is not backwards compatible with versions of this middleware prior to
# faraday_middleware v0.12 - prior to this version, we used YAML.load rather than
# YAMl.safe_load, which exposes serious remote code execution risks - see
# https://github.com/ruby/psych/issues/119 for details. If you're sure you can trust
# YAML you're passing, you can set up an unsafe version of this middleware as follows:
#
# class UnsafelyParseYaml < FaradayMiddleware::ResponseMiddleware
# dependency do
# require 'yaml'
# end
#
# class SafeYaml < FaradayMiddleware::ParseYaml
# define_parser do |body|
# YAML.safe_load(body)
# YAML.load body
# end
# end
#
# Faraday.new(..) do |config|
# config.use SafeYaml
# config.use UnsafelyParseYaml
# ...
# end
class ParseYaml < ResponseMiddleware
dependency 'yaml'
dependency do
require 'safe_yaml/load'
end

define_parser do |body|
::YAML.load body
SafeYAML.load body
end
end
end
Expand Down

0 comments on commit f21384b

Please sign in to comment.