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
Mash.load is insecure #575
Comments
Yes, this looks like a problem, at least in the documentation. Hopefully people only use it to load YML files, which seems to be the case. I propose three things:
Want to take it on? |
Cool yea it seems applications are just using it to load their own config files and not on user-provided files. I noticed as I was making a little script for dealing with json responses from an api (yaml.safe_load also parses json), hashie is a nice library that makes it convenient to deal with :). But the api could return stuff with ruby in erb templates and run code on my computer if I used
I'm about one week in to learning ruby, I work pentesting so I've audited a handful of rails apps and have some experience reading ruby code, just not writing it. It seems like a straightforward enough first task so I'll give it a try, but definitely review my attempt and change anything that's not good ruby style. |
|
Interesting read, thanks! I'm not too worried as I'm not using it in a program, it's just for interactive use in the shell. It's for a little script that can go in the middle of unix pipelines and open pry with the data. If the data is json it will load it into a Mash. I used to use jq but I can never remember the syntax. With ruby + mash it is almost as concise as jq which is nice for interactive data fiddling, more consistent and easier to remember, and more powerful as you have a full general purpose programming language |
waxing nostalgic: Many moons ago, I set about ripping Unfortunately, I never pushed that repository remotely and the hard drive on which that work lived died a scratchy death so I don't have that work anymore. suggestion: Anyway, if you're only using it for accessing data and not writing it, perhaps hash_with_dot_access would work for your use case. It gives you the method access capabilities of Mash without a lot of the accompanying baggage. It doesn't have a #!/usr/bin/env ruby
require "hash_with_dot_access"
require "json"
class Accessor < BasicObject
def initialize(file)
return unless ::File.exist?(file)
@data =
::File
.read(file)
.then { |content| ::JSON.parse(content) }
.then { |json| ::HashWithDotAccess::Hash.new(json) }
end
def method_missing(method_name, ...)
return super unless @data.key?(method_name)
@data.__send__(method_name)
end
def respond_to_missing?(method_name, include_private = false)
@data.key?(method_name) || super
end
end
file_name, *commands = ARGV
puts Accessor.new(file_name).instance_eval(commands.join("")).inspect For file {"my": {"deeply": ["nested", "data"]}} You could do:
to get:
It has a bunch of gotchas (e.g. |
Using Mash.load on untrusted input is insecure, as it calls
ERB.new
, which will execute arbitrary ruby code. This might seem obvious as the example in the documentation shows using ERB, but the documentation also says it callsYAML.safe_load
and includes permitted_symbols and permitted_classes options intended for controlling the security of loading yaml, so it seems to imply there is some sort of security control. I think Mash.load should be secure by default and only run ERB.new if you explicitly pass an option to use it, or at least the documentation should be updated with a warning so it's more clear that people shouldn't run Mash.load on untrusted inputThe text was updated successfully, but these errors were encountered: