ぶちのブログ

競プロとCTFが趣味なWebエンジニアのアウトプットの場

gem install bundleの罠

TL;DR

ネタ記事です。Aliasのためだけに存在しているgemがあるというお話を少し掘り下げています。

はじめに

Rubyを使って開発していると、ふいにbundle installが使えず、慌ててgem install bundleと打ってしまうってことありませんか?
(ちなみに、最近のRubyではbundlerがデフォルトで入っているので、bundle installが通らないなんてことはかなり減りましたが、、)

正しくは、gem install bundlerです。

そんなことはしないよと思った方、ぜひgem list | grep bundleを実行してみてください。

bundle (0.0.1)
bundler (x.x.x)

と表示される方は意外と多いのではないでしょうか?気づかぬうちにbundleというgemがインストールされていませんか?

gem install bundleとすると何が起こるのでしょう。bundleを調べると、このgem自体は空で、依存関係にbundlerが設定されていることがわかります。
つまり、gem install bundleによってbundlerもインストールされるので、全く問題なく動きます。

実害はちょっとだけ環境を汚されてしまうことだけです。 (もしこのgemの作者が悪意を持っていたら結構怖い事になると思いますが、完全に善意のようですね。)

驚くことに、このgemは約478万回(2020/01/02時点)もダウンロードされており、例えばpuma_worker_killer(約481万ダウンロード)と同程度にダウンロードされています!

うまくAliasを貼っただけのgemを作れば、これだけのダウンロード数のgem作者になれるわけです!
他にもこういったgemはありそうなので調べてみました。

gemのlistを集める

robots.txtを見るとスクレイピングは禁止っぽいです。
どうしようと思ったらちゃんとデータが配布されているので、こちらからダウンロードします。

bundlerに似たgemを集める

雑にbundlerとのレーベンシュタイン距離が1のgemを探します。levenshtein-ffiというgemを使って計算しました。

require 'levenshtein'

gems = File.read('gem_list.txt').split
similar_gems = gems.select do |gem|
  Levenshtein.distance('bundler', gem) == 1
end

puts similar_gems
bindler
bndler
bundle
bundlr
bungler
bunlder
byndler
fundler
jbundler
rundler
vundler

なんかたくさんある!この中からAliasじゃないgemを除きます。

bundle 約478万ダウンロード
bunlder 約38000ダウンロード
bundlr 約5500ダウンロード
byndler 約4000ダウンロード
bndler 約3000ダウンロード

結局見つかったのはこの5つでした、そして、ダウンロード数はbundleが圧倒的でした。

考察

bundlerはよく使うコマンドがbundleだったため、bundleという間違えが多い。これはtypoというよりは勘違いに起因している気がしました。 bunlderに関してはtypoだが、ダウンロード数はそれほど多くないようです。

また、同種の間違いをしているgem、例えばraislなどは、比率で考えても更に少ないダウンロード数でした。
Gemfile経由でダウンロードする際には間違えにくいような気がします。

「コマンドとgem名が違う」「Gemfile経由でダウンロードすることが少ない」などの好条件を満たさないと、bundleほどのダウンロード数を作れなさそうです。

おわりに

1年半くらい前に自分のgem listを見て気づいたネタをやっと供養できました。