ソースコードアーカイブとハッシュの今後の安定性に関する最新情報
Published at February 21, 2023
Category: Product,Git
Author: Matt Cooper

2023年1月30日、GitHubはソースコードのダウンロード時の圧縮設定を若干変更する変更を導入しました。この変更は、多くのコミュニティにとって予期せぬ結果となり、その報告を受けた後、私たちはこの変更を元に戻しました。何が起こったのか、予期せぬ事態を防ぐためにどのような対策をとっているのか、そして今後の変更にどのように対処するのかを説明したいと思います。
以下がその内容です。
GitHubでのソースのダウンロードは、Gitのarchiveコマンドに依存しています。GitHubのデータ量が多いため、私たちはgitアーカイブの
結果を永久に保持しません。一時的にキャッシュされ、その後削除され、再び要求されたら再作成されます。これは、リリースやタグ、そして任意のコミットを、ストレージの必要量を維持できないレベルまで膨らませることなく利用できるようにするための、良いバランスを保っているのです。
1月30日には、ソースのダウンロードを支援するサービスにGit 2.38をデプロイしました。このバージョンのGitは、gitアーカイブの
生成に使われるデフォルトの圧縮コマンドを、外部のgzipから
内部のgzip
コピーに変更しました。アーカイブに含まれるファイルは同一でしたが、圧縮設定の小さな変更は、アーカイブ自体のバイトレイアウトが変わることを意味しました。これは、アーカイブのハッシュや チェックサム(SHA256, CRC64 など) も変化することを意味します。
その結果として、多くのコミュニティがソースのダウンロードとそのハッシュについて想定していました。再現性やセキュリティを確保するために、多くのシステムはアーカイブを一旦集中的にダウンロードし、そのハッシュを自分たちのリポジトリに記録しています。後でユーザーが GitHub からアーカイブをダウンロードすると、そのクライアントは自動的にアーカイブのハッシュを、先に記録されたものと照合します。もし不一致があれば、クライアントは処理を拒否します(何かが変わったのであれば、それが改ざんされたものなのか、壊れたダウンロードなのか、それとも他のものなのかを人間が判断する必要がある、という想定で)。
この結果が予想外のものだったか
イエスでもありノーでもあります。私たちは、git archive
コマンドのデフォルトが変更されたことは知っていました。予想外だったのは、このことが多くのコミュニティに広く影響を与えるかもしれないということです。
内部的には、私たちは長い間git archive
のバイト単位の安定性を保証すべきではないと考えてきました。デフォルトや利用可能なオプションさえも、Gitプロジェクトによってコントロールされており、同様にそのような保証はしていないのです。私たちは、私たちがフォークしたGitと上流のGitとの間の差異を最小にするよう努力しています。したがって、archive
コードに恒久的なパッチを持ち込むことは避けたいと考えています。
しかし、今回の事件で、私たちはこのスタンスを必ずしも明確にしていなかったことを知りました。今、私たちがすべきことは、このスタンスをコミットすることです。このコミットメントに加え、私たちは開発サイクルにテストを追加し、将来的な変更をGitHub.comに反映する前に検出できるようにします。(GitHub Docsはこのコミットメントを反映するためにまもなく更新されます)
アーカイブとハッシュの将来的な安定性
- GitHubは、今日から1年以上(2023年2月21日)、ダウンロードしたソースをバイト単位で安定的に保持する予定です。これはtarball (.tar.gz) とzipball (.zip)の両方の形式をカバーしています。
- 将来、どちらかのアーカイブ形式を変更する場合は、6ヶ月前にドキュメント、ブログ、変更履歴でお知らせします。(圧縮パスに重大な脆弱性が発見された場合、私たちのシステムとお客様を保護するために、通知期間を短縮または省略する権利を留保します。このような結果は想定していませんが、わからないものです)。
- この変更がもたらす影響の大きさを改めて認識したため、現在のところ、どちらのフォーマットも変更するつもりはありません。完全な透明性を保つために、私たちが修正したいと思ういくつかの欠陥 (zipball に埋め込まれたタイムスタンプ、tarball のシステム
gzip
への依存) がありますが、当面の間、私たちはこれらの小さな問題を回避するように設計します。
もしあなたが再現性のためだけに安定したアーカイブに依存しているのなら (アーカイブの中に常に同一のファイルがあることを保証するため)、私たちはソースアーカイブをソースアーカイブ REST API を使って、:ref
パラメータにコミット ID を指定してダウンロードすることをお勧めします。ハッシュを記録する必要はありません。コミットIDによって、アーカイブ内のファイルの内容が常に同じであることが保証されるからです。GitとGitHubは、コミットIDの生成方法の性質上、これを保証しています。コミットIDを使うことで、リポジトリがタグを書き換えたりブランチヘッドを移動したりしても、影響を受けないようになります。tarball と zipball の形式には、切り捨てに対する保護が組み込まれています。また、TLS (HTTPSによる) によってアーカイブの破損を防いでいます。
セキュリティのために安定したアーカイブに依存している場合 (たとえば、誤って tarbomb を起動しないようにする)、ソースのダウンロードを使う代わりに、リリースアセットに切り替えることをお勧めします。リリースページでは、GitHubにアップロードされたアセットがファイルサイズとともに表示されます。ファイルは、ウェブから手動で追加するか、この(サードパーティ製の)GitHub Actionのようなものを使ってリリースに追加することができます。後でRelease Assets REST API を使ってファイルを取得することもできます。リリースアセットに依存することが不可能な場合は、将来の(頻繁ではない)ハッシュの変更に対応できるような設計を検討することを強くお勧めします。
Source
Update on the future stability of source code archives and hashes
On January 30, 2023, GitHub deployed a change which slightly altered the compression settings on source code downloads. This change had unforeseen consequences for a number of communities, and after they let us know, we rolled the change back. We’d like to explain what happened, what measures we’re …