Skip to content

Instantly share code, notes, and snippets.

@claudijd
Created September 6, 2018 17:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save claudijd/f88803af5c44e817678b3eb95f056b93 to your computer and use it in GitHub Desktop.
Save claudijd/f88803af5c44e817678b3eb95f056b93 to your computer and use it in GitHub Desktop.
Crude mechanism to detect typo attacks on RubyGems
require 'levenshtein-ffi'
class String
def edit_distance(other)
raise unless other.is_a?(::String)
diff = Levenshtein.distance(self, other)
end
end
# Arbitrary gem list to test to determine if they are bad or not
unknown_gem_names = [
"bundler",
"budlner",
"bundler2",
]
good_gem_names = [
"bundler",
"nokogiri",
"bindata",
"c7decrypt",
]
exception_gem_names = [
"bundler2",
]
unknown_gem_names.each do |unknown_gem_name|
if good_gem_names.include?(unknown_gem_name)
puts unknown_gem_name + " is a known good gem, proceed"
next
end
good_gem_names.each do |good_gem_name|
malware_detected = false
if good_gem_name.edit_distance(unknown_gem_name) <= 2
if exception_gem_names.include?(unknown_gem_name)
puts unknown_gem_name + " is a close match to #{good_gem_name}, but we've added an exception, proceed"
else
puts unknown_gem_name + " is a close match, possible malware"
malware_detected = true
end
end
break if malware_detected == true
end
puts unknown_gem_name + " is not a close match, proceed"
end
@claudijd
Copy link
Author

claudijd commented Sep 6, 2018

Output looks something like this...

$ ruby ~/Desktop/malicious_gem_name_poc.rb 
bundler is a known good gem, proceed
budlner is a close match, *possible malware*
budlner is not a close match, proceed
bundler2 is a close match to bundler, but we've added an exception, proceed
bundler2 is not a close match, proceed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment