新しいGitバージョン2.30.2では、Git2.15以降に影響を与えているGitラージファイルストレージ(LFS)と他のクリーン/スマッジフィルターのセキュリティの脆弱性が修正される。
これらの更新で、シンボリックリンクをサポートする大文字と小文字を区別しないファイルシステムにおいて、gitクローン中に細工されたリポジトリがコードを実行できる問題に対処しています。このコードの実行は、Git LFSで構成されたものなど、特定の種類のクリーン/スマッジフィルターを悪用することによるものです。
CVE ID CVE-2021-21300で記録されたこの脆弱性は、WindowsシステムとmacOSシステムのすべてのユーザにとって特に懸念事項となる。それらのシステムでは、デフォルトで大文字と小文字を区別しないファイルシステムが使用される。また、Gitリポジトリをチェックアウトするために、大文字と小文字を区別しないファイルシステムを使用するLinuxなどのすべてのシステムに影響を与える可能性がある。
PythonプログラマのFoone Turing氏はTwitterスレッドで、かなり長く詳細に脆弱性の分析を提供した。一言で言えば、この悪用には2つのステップが必要である。lstat
キャッシュを不正な状態にすることと、チェックアウト操作を並べ替えることである。キャッシュを不正な状態にする1つの方法は、ファイル名の衝突を引き起こして、大文字と小文字を区別しないファイルシステムを悪用することである。チェックアウトの並べ替えは、チェックアウトを遅らせてクリーン/スマッジフィルターを使用することで実行できる。これは、Git LFSが最も注目すべき例である。これらが、悪用を可能にする2つの要素である。
クリーン/スマッジフィルターについては、ファイルを操作するためにローカルの変更が必要となるが、それらの変更をコミットし直したくない場合に使用される。この例としては、行末形式やデプロイメント固有の情報の変更があり、これは開発システムで作業するときにオーバーライドする必要がある。Git LFSは、クリーン/スマッジフィルターを使用して、URLをGitリポジトリに保存されている大きなファイルに変換してファイル自体に変換する。そのファイル自体は、リポジトリでの作業時に保存場所から自動的にダウンロードされる。
クリーン/スマッジフィルタを使うだけでは脆弱性を引き起こすには不十分である。フィルタを適用しても通常はチェックアウトの順序が変更されないためである。遅延チェックアウトが使用されていない限り、つまり、Git LFSを使用すると、ダウンロードの進行中に、非常に大きなファイルのダウンロードによってリポジトリ内の残りのファイルのチェックアウトが一時停止となることを防ぐことができる。この結果、大きなファイルは、実際のチェックアウト順序を順守せず、ダウンロードが完了するのを待たずにGitが処理できる他のファイルの後にチェックアウトされる。
この情報を踏まえると、次のコードを理解できる。これは、脆弱性の悪用のデモである。
#!/bin/sh
git init delayed-checkout &&
(
cd delayed-checkout &&
echo "A/post-checkout filter=lfs diff=lfs merge=lfs" \
>.gitattributes &&
mkdir A &&
printf '#!/bin/sh\n\necho PWNED >&2\n' >A/post-checkout &&
chmod +x A/post-checkout &&
>A/a &&
>A/b &&
git add -A &&
rm -rf A &&
ln -s .git/hooks a &&
git add a &&
git commit -m initial
) &&
git clone delayed-checkout cloned
ご覧のとおり、悪意のあるA
ファイルは最初にリポジトリに追加され、次に削除され、悪意のないa
シンボリックリンクを通して置き換えられる。これらの2つのファイルは、大文字と小文字を区別するファイルシステムで衝突を引き起こすことはない。Gitがすべての操作を同じ順序で再生できる場合も、衝突は発生しない。このケースとなるのは、一連の操作でファイルシステム名の衝突を引き起こすことができないためである。ファイルシステムによって衝突させることができず、Gitキャッシュが正常なままになるためである。ただし、チェックアウトを並べ替えることで、A
を悪用してGitキャッシュに配置して、クローン中に実行することができる。
この悪用は、大文字と小文字を区別しないファイルシステムとGit LFSの使用に限定されないことに注意してください。これは、ファイルシステム名の衝突があり、チェックアウトの遅延とともにクリーン/スマッジフィルターが使用されている場合にトリガーされる。
短い発表で、GitHubは脆弱性の影響を受けないと述べました。
GitHub自体はこの攻撃に対して脆弱ではありません。クリーン/スマッジフィルターを使用しないGitHub Pagesを除いて、チェックアウトしたリポジトリのコピーをサーバに保存しません。
GitHubによると、Gitをバージョン2.30.2にアップグレードするオプションがない場合、ユーザは3つの方法でリスクを軽減できる。まず、core.symlinks
構成オプションをfalseに設定して、シンボリックリンクのサポートを無効にすることができる。または、プロセスフィルターをfalse
にすることもできる。最後の方法としては、信頼できないリポジトリのクローンを作成しないことである。