Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Patch YAML to allow only some Gem classes to be unmarshalled
  • Loading branch information
sj26 committed Jan 31, 2013
1 parent c69bd75 commit 334bff6
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions config/initializers/forbidden_yaml.rb
@@ -0,0 +1,59 @@
# XXX: This is purely a monkey patch to close the exploit vector for now, a more
# permanent solution should be pushed upstream into rubygems.

require "rubygems"

# Assert we're using Psych
abort "Use Psych for YAML, install libyaml and reinstall ruby" unless YAML == Psych

module Psych
class ForbiddenClassException < Exception
end

module Visitors
class WhitelistedToRuby < ToRuby
WHITELIST = %w(
Gem::Dependency
Gem::Platform
Gem::Requirement
Gem::Specification
Gem::Version
Gem::Version::Requirement
)

private

def resolve_class klassname
raise ForbiddenClassException, "Forbidden class in YAML: #{klassname}" unless WHITELIST.include? klassname
super klassname
end
end
end
end

module Gem
class Specification
def self.from_yaml input
input = normalize_yaml_input input
nodes = Psych.parse input
spec = Psych::Visitors::WhitelistedToRuby.new.accept nodes

if spec && spec.class == FalseClass then
raise Gem::EndOfYAMLException
end

unless Gem::Specification === spec then
raise Gem::Exception, "YAML data doesn't evaluate to gem specification"
end

unless (spec.instance_variables.include? '@specification_version' or
spec.instance_variables.include? :@specification_version) and
spec.instance_variable_get :@specification_version
spec.instance_variable_set :@specification_version,
NONEXISTENT_SPECIFICATION_VERSION
end

spec
end
end
end

0 comments on commit 334bff6

Please sign in to comment.