Skip to main content

PyPIのPythonパッケージの10%以上がライセンスなしで配布されている

著者
Headshot of Tal Einat

Tal Einat

Over of Python Packages on PyPI are Distributed Without Any License tumb

2018年9月18日

0 分で読めます

PyPIから適当なPythonパッケージをインストールしたとしましょう。そのパッケージにライセンス情報がない確率は、なんと13.5%です。一般的なPythonアプリケーションには、数百もの依存関係や間接依存関係が含まれることも珍しくありません。そのため、ライセンスのないコードを使用している可能性はかなり高いといえます。ライセンスのないソフトウェアを使った場合の影響は、状況によって、取るに足らないものから甚大なものまでさまざまです。ずいぶん幅がありますね。この記事では、この問題をさらに掘り下げます。

PyPIとは?

PyPIは、Python Software Foundationが作成・運営する、Pythonパッケージで最も広く使われている中央リポジトリです。通常、pipなどのパッケージ管理ツールを使ってアクセスし、Pythonライブラリやアプリをダウンロード、インストールします。これは、Javascriptのnpm、RubyのRubyGems.org、Rustのcrates.ioなど、ほかの言語のパッケージリポジトリと同様です。

背景

Snykはソフトウェアプロジェクトの依存関係を分析し、セキュリティ脆弱性や不適切なライセンスなどの問題を検出します。そのため、最近、PyPIにあるパッケージとリリース済みバージョンのメタデータ(ライセンス情報を含む)をすべて取得する仕事を依頼されました。このデータをもとに、PyPI上のすべてのPythonパッケージのライセンス状況を調査しました。

以下では、この分析から得られた主な知見と、それを踏まえた提案、そして分析に用いた手法を紹介します。

Pythonエコシステムのライセンス状況は?

まず、簡単にお断りしておきます。私は弁護士ではありません。ソフトウェアエンジニアとしての経験があり、ソフトウェアライセンスについて多少の知識はありますが、専門家ではありません。以下の内容は法的助言ではありませんので、必要に応じて弁護士に相談することをおすすめします。

ライセンスの種類

一般に、ほぼすべてのオープンソースソフトウェアライセンスは、いくつかの大まかなカテゴリーに分類できます。

  • 「コピーレフト」ライセンスは比較的制約の強いライセンスで、よく知られているGPLライセンスとその多くの派生ライセンス、類似ライセンスが含まれます。これらのライセンスでは、ソフトウェアをほぼあらゆる目的で使用できますが、変更を加えた場合は、その変更内容も公開する必要があります。さらに、一部の「強い」コピーレフトライセンスでは、特定の状況下において、そのライセンスのソフトウェアを使用するコードも公開することが求められます。

  • 一方、「パーミッシブ」ライセンスでは、変更内容を公開せずにソフトウェアを改変できます。また、一般によりシンプルで、制約も少ないライセンスです。

  • さらに制約が少ないのが、一般に使用に関する制限を一切設けない「パブリックドメイン」ライセンスです。

コピーレフトとパーミッシブのライセンスに関する詳しい解説は、以前のブログ記事をご覧ください。

近年、「弱いコピーレフト」ライセンスがいくつか登場しました。これらは主にソフトウェアライブラリを対象としており、利用するソフトウェアに対する制限を軽減、あるいはなくすことを認めています。「弱い」コピーレフトと「強い」コピーレフトの違いについては、該当するWikipediaの記事の節をご覧ください。

ライセンスを指定しないことも可能ですが、推奨はされません。多くの場合、見落としか知識不足によるものですが、まれに意図的に指定しないケースもあります。ライセンスがなければ、そのソフトウェアの使用には(各国の)著作権法や、特許法などのほかの法律が適用されます。

ライセンスの種類の内訳

PyPIで使われているライセンスの種類を見てみましょう。

「ライセンス種別のおおよその内訳」と題された円グラフ。BSD系 63.9%、強いコピーレフト 18.3%、ライセンスなし 13.5%、弱いコピーレフト 3.3%、パブリックドメイン 1.0%。

このデータから、次のことがわかります。

  • PyPI上のパッケージの大半にあたる64%は、MIT、Apache 2.0、2条項または3条項のBSDライセンスなどの「パーミッシブ」ライセンスを使用しています。

  • 18.5%は、GPLやAGPLなどの「強いコピーレフト」ライセンスを使用しています。

  • 3%は、LGPLやMPLなどの「弱いコピーレフト」ライセンスを使用しています。

  • CC0、WTFPL、Unlicenseなどの「パブリックドメイン」ライセンスを使用しているのは、わずか1%です。

  • 13.5%にはライセンスが含まれていません。

これは意外な結果ではありません。GitHubや、ほかの言語のパッケージリポジトリで見られる全般的な傾向と同様です。

Pythonパッケージで最もよく使われているライセンス

PyPIでは、MIT、BSD-2-Clause、GPL-3.0、Apache-2.0の4つのライセンスが主流です。

「最も一般的なライセンス」というタイトルの円グラフ。MIT 42.7%、BSD-2-Clause 16.9%、GPL-3.0 13.6%、Apache-2.0 10.9%、その他 15.9%。

ほかにも広く使われているライセンス(100以上のパッケージで使用)があります。そのうち、Pythonエコシステム特有のものが2つあります。Python Software Foundationライセンス(PSF)とZope Public License(ZPL)です。

「その他の一般的なライセンス」というタイトルの棒グラフ。AGPL-3.0が約4.4%で最も多く、次いでLGPL-3.0、GPL-2.0となっている。

今すぐすべきこと!

PyPI上のPythonパッケージのライセンス状況を踏まえ、次のことを強くおすすめします。

  • 「コピーレフト」ライセンスのソフトウェアを直接または間接的に使用していないか確認し、自分のコードに及ぼす影響を理解しておきましょう。

    1. プロプライエタリ(オープンソースではない)コードを書いている場合、特にPyPIパッケージの18%以上で使われている「強いコピーレフト」ライセンスは、重大な法的リスクにつながる可能性があります。

    2. オープンソースソフトウェアを書いている場合、同様のライセンス条件でコードをライセンスするよう求められる可能性があります。

  • ライセンスが指定されていない依存関係がないか確認しましょう。

    1. そのような依存関係を変更する必要がある場合や、将来変更する可能性がある場合、著作権法上、変更が認められないことがあります。

    2. こうした依存関係の将来のバージョンでライセンスが追加される可能性は高いものの、どのようなライセンスになるかはわかりません。

  • 依存関係のライセンスを定期的または継続的に確認する自動ツールを導入しましょう。

    1. プロジェクトのライフサイクルを通じて、依存関係は頻繁に追加・変更されます。

    2. 依存関係のライセンスはバージョン間で変わることがあるため、バージョンをアップグレードするとライセンスも変更される可能性があります。

さらに詳しく

ここで紹介したのは、ほんの入り口にすぎません。ライセンスは思っている以上に重要かもしれません。ぜひ、さらに調べてみてください。次のテーマについて学ぶことをおすすめします。

方法

データの収集と分析をどのように行ったか、詳しく説明します。

まず、PyPI上のすべてのパッケージと、リリース済みの全バージョンのメタデータを収集しました。2018年8月上旬に数日かけて実施しました。当時、PyPIには約15万のパッケージがありました。

次に、各パッケージの各バージョンについて、「license」と「classifiers」の両フィールドからライセンス情報を抽出しました。その後、バージョンをセマンティックバージョニング方式に基づいて並べ替え、単一のデータ構造に集約しました。

次に、ライセンスデータを整理し、正規化しました。Snykで使われているSPDXライセンス正規化ツールのバージョンをベースに、より多くのライセンスを正しく認識できるよう、正規化ツールを繰り返し改良しました。さらに、例外的なケースを網羅するため、特殊ケースの大規模な対応表を手作業で作成しました。

その後、ライセンスのないパッケージのうち18%を分析することにしました。この時点では、リリースに含まれるファイルをまだ確認していませんでした。ライセンスのないパッケージを無作為に50個選び、最新リリースをダウンロードしてライセンス情報を探しました。情報を集めた後、これらのパッケージを次の5つのカテゴリーに分類しました。

「ライセンス情報のないパッケージのサンプル内訳」というタイトルの円グラフ。ライセンスありとなしが各28%、プレースホルダーが14%、使い捨てが18%、そして

実際にライセンスがあるのは、「Licensed」カテゴリーのものだけです。「training」「throwaway」「placeholder」カテゴリーのパッケージの大多数には何らかのコードが含まれており、意図的に、あるいはタイプミスなどの間違いによって、依存関係として使われる可能性があります。そのため、これらは実際にライセンスのないパッケージとみなすのが妥当だと判断しました。このサンプルをもとに推計すると、PyPI上のパッケージの約18% × 72% = 約13.5%にライセンスがありません。

なお、PyPI上でライセンスがあるパッケージについては、同様の分析を行っていません。ライセンスが記載されていても、「training」「throwaway」「placeholder」に該当するパッケージは多数あると考えられます。そのため、PyPI上の「実際の」パッケージのうち、ライセンスのないものは約18% × 28% = 約5%にすぎないと保守的に推計するのは、実態を大きく見誤る可能性があります。残念ながら、そこまで分析する時間がなかったため、上記の分析にとどめました。

ご質問やご意見があれば、ぜひお聞かせください。Twitterの@taleinatまでご連絡ください。

CTFを始めよう

オンデマンドのバーチャル入門ワークショップを視聴して、CTFの課題の解き方を学びましょう。

続きを読む

feature insights context
Blog

自律型攻撃はすでに始まっている。防御もそのスピードに追いつかなければならない。

自律型攻撃者によって、防御に使える時間は短くなっています。継続的な検出、修復、検証、予防で、セキュリティチームが攻撃に歩調を合わせる方法をご紹介します。

feature insights context
Blog

予防は、本質的に解決済みの問題なのでしょうか?

エージェントが生成するコードの予防策はアーキテクチャ上解決されていますが、開発を遅らせることなくセキュリティを守る制御を選ぶことが、依然として課題です。

Live Stream

修正エージェントをわかりやすく解説:見つけるより直すことが重要な理由

SnykのRemediation Agentが、セキュリティインテリジェンス、破壊可能性分析、検証を活用して、脆弱性をマージ可能なプルリクエストに変える仕組みをご覧ください。