-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parse YAML safely #157
Parse YAML safely #157
Conversation
spec/unit/parse_yaml_spec.rb
Outdated
it "returns false for empty body" do | ||
expect(process('').body).to be false | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that the new safe_yaml is supposed to return nil
. Can we test that rather than deleting the test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
YAML.safe_load
(which is part of Psych in Ruby from 2.x onwards) returns nil
.
But the safe_yaml
gem returns false
still, unfortunately. Rather than have a conditional test, I elected to remove this. We have to use safe_yaml
because Psych.safe_load
doesn't exist in Ruby 1.x. The better solution would be to stop supporting Ruby 1.x, which would vastly improve this code, and makes sense given that 1.9 reached end of life more than 2 years ago.
Psych.safe_load body | ||
else | ||
SafeYAML.load body | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit short on time so can you please expose the difference between one and the other?
How would this code change, assuming we might drop support for some ruby versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Psych (which is included in Ruby), from Ruby 2.x onwards, includes the safe_load
method. Using SafeYAML
is a way of backporting this for Ruby 1.x.
If we dropped support for old Ruby versions, then we wouldn't need an if
statement, we could remove SafeYAML
and just use Psych
.
@iMacTia Thanks for getting back to me on this - really appreciate it! |
Actually, ignore my previous comments - I have a better plan! A version of Psych has been included in Ruby's STDLIB since 1.9.2. However, and fortunately, you can install a newer version of Psych using RubyGems, which supports I'm going to implement this approach now. __The only slight cost is it will require us to drop support for Ruby 1.8.x, but that isn't supported by Faraday anyway, and is way out of date, having been EOL'd in early 2013. |
Thanks for the detailed explanation @timrogers!
After reading your comments, my understanding is that SafeYAML gem is available for all ruby versions we support and has the same identical behaviour as the current release (return false in case of empty body). That makes it, for me, the best option we have. |
Going for
Second point is extremely important and makes me looking at the |
@iMacTia That makes sense. Let me try with |
This is now using We should still make sure people are aware that this is breaking in some sense (it'll no longer unsafely parse by default!), but I think it's highly likely that few or zero people are actually doing this. @iMacTia Does this look good to you? |
I agree this is the best solution we could go for :) I'll review the code one last time if tests are all green. |
@iMacTia Passing now! |
@timrogers Please don't @-mention someone in a commit and then rebase the heck out of that commit repeatedly. 😉 |
ahaha he wanted to be sure you got notified. I guess that worked 😃 |
approved and marked for v0.12 |
@iMacTia Do you have a view on when v0.12 is likely to go live? 🚀 |
Unfortunately not at the moment. Sorry! |
* Partially resolves #272 * Full fix: wait for lostisland/faraday_middleware#157 to be merged
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @timrogers, I'm trying to get release 0.12 ready to ship.
I realised you added safe_yaml to the gemspec and this made it dependency that will be installed with faraday_middleware. However, we only want that dependency to be considered if you use the Yaml middleware, so can you please remove it from there and move it to the Gemfile (for rspec)?
dependency 'yaml' | ||
dependency do | ||
require 'safe_yaml/load' | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we specify the actual dependency here?
dependency 'safe_yaml' do
require 'safe_yaml/load'
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks from Faraday::Middleware.dependency
(https://github.com/lostisland/faraday/blob/a712938071bb0997410b5de4a4f2517d30fc4d3d/lib/faraday/middleware.rb#L13) that you either supply a block or a string to require. I'll change this to dependency 'safe_yaml/load'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got mad looking for that method, and it was in Faraday::Middleware 🤦♂️
Agree with you that `dependency 'safe_yaml/load' is better then
faraday_middleware.gemspec
Outdated
@@ -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' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't add the dependency here, add it on the Gemfile so the gem won't be installed with Faraday
An issue from June 2014, #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.
@iMacTia Done! |
Github is not showing any new commit, are you sure you pushed your latest changes? |
Sorry! I thought I'd pushed but the connection failed. Should be there now. |
* lostisland/faraday_middleware#157 * Now merged, so lets update the gem!
* lostisland/faraday_middleware#157 * Now merged, so lets update the gem!
An issue from June 2014, #92, raises the risks of the current
FaradayMiddleware::ParseYaml
middleware which usesYAML.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 using Ruby's built-in
Psych.safe_load
for Ruby 2.0.0 and onwards, or otherwise uses thesafe_yaml
gem for earlier versions.