Skip to content

Instantly share code, notes, and snippets.

@jeviolle
Forked from dcu/check_gems.rb
Last active April 7, 2016 15:32
Show Gist options
  • Save jeviolle/59cc2f928436cae152d2f672749821a0 to your computer and use it in GitHub Desktop.
Save jeviolle/59cc2f928436cae152d2f672749821a0 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#http://blog.rubygems.org/2016/04/06/gem-replacement-vulnerability-and-mitigation.html
require 'rubygems' # for older rubies
require 'rest-client'
require 'bundler'
require 'time'
require 'json'
CHECK_GEMS_BEFORE = Time.parse("Feb 9, 2015")
def check_bundler
gems = Bundler::LockfileParser.new(Bundler.read_file("Gemfile.lock"))
gems.specs.each do |spec|
gem_name = spec.name
version = spec.version.to_s
next unless spec.source.kind_of?(Bundler::Source::Rubygems)
rubygems = spec.source.remotes.find {|r| r.to_s =~ /rubygems\.org/ }
if gem_name !~ /-/ || rubygems == nil
next
end
check_gem(gem_name, version)
end
end
def check_local_gems
Gem::Specification.each do |gem|
if gem.name =~ /-/
check_gem(gem.name, gem.version.to_s)
end
end
end
def check_gem(gem_name, version)
print "Checking #{gem_name} #{version}"
response = RestClient.get("https://rubygems.org/api/v1/versions/#{gem_name}.json") {|r| r }
if response.code != 200
puts " [NOT FOUND]"
return
end
gem_data = JSON.parse(response)
gem = gem_data.find {|gd| gd["number"] == version }
if !gem
puts " [NOT FOUND]"
return
end
created_at = Time.parse(gem["created_at"])
if created_at < CHECK_GEMS_BEFORE
puts " [UNVERIFIED]"
else
puts " [SAFE]"
end
end
if File.exist?("Gemfile.lock")
check_bundler
else
check_local_gems
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment