📑

git clone時に自動でAIに危険性を分析させるツールを作った

2025/03/10に公開

はじめに

みなさん、GitHubなどからリポジトリをクローンするとき、そのコードが安全かどうか考えたことはありますか?

最近、こんな記事を読みました。

https://zenn.dev/mameta29/articles/7aa221046a87ff

リポジトリをクローンして危険性の検証なしに実行してしまったことからハッキングに繋がった事例です。怖いですよね。
対策として、記事やコメントでも触れられていますが、クローンしてから実行するまでの間に、AIに投げてコードの安全性をチェックしてもらうことで、危険なコードを実行する可能性を大きく減らすことができます。

そこで作ったのが git-safe-clone です。

git-safe-clone の概要

git-safe-clone は、リポジトリをクローンする前に安全性を確認するための Git カスタムサブコマンドです。クローンしたリポジトリは dockerコンテナ内のOpenHandsによるチェックが行われ、危険と判断された場合にはクローンしたディレクトリが自動的に削除されます。

インストール方法

https://github.com/kbwo/git-safe-clone#installation を参照してください

基本的な使い方

git safe-clone <repository-url> [<git cloneと同じオプションを受け付けます>]

通常の git clone コマンドとほぼ同じ感覚で使えます。違いは、クローン後に自動的にセキュリティチェックが行われることです。

例えば:

# 基本的な使い方
git safe-clone https://github.com/example/repo.git

# カスタムディレクトリ名を指定
git safe-clone https://github.com/example/repo.git my-custom-dir

# git cloneオプションを指定
git safe-clone https://github.com/example/repo.git --depth=1

動作の仕組み

  1. 指定されたリポジトリを通常通り git clone します
  2. クローンしたリポジトリのコードを repomix を使って1つのファイルにまとめます(大きすぎる場合は分割)
  3. OpenHands を Docker コンテナ内で実行し、LLM を使ってコードベースを分析します
  4. 分析結果に基づいて、リポジトリが安全かどうかを判断します
    • 安全と判断された場合、クローンされたディレクトリはそのまま残ります
    • 安全でないと判断された場合、クローンされたディレクトリは自動的に削除されます

なぜOpenHandsを使ったのか

OpenHandsは、LLMを活用したAIエージェントフレームワークであり、以下の理由からgit-safe-cloneに採用しました:

  1. エージェント形式の柔軟性: OpenHandsはエージェント形式のツールであるため、単純なプロンプト&レスポンスの枠を超えた複雑な分析が可能です。プロンプトの設定次第で、コードの安全性診断をより自律的かつ詳細に行うことができます。

  2. カスタマイズ可能な分析プロセス: プロンプトをカスタマイズすることで、特定のセキュリティ脆弱性に焦点を当てたり、特定の言語やフレームワークに特化した分析を行わせることができます。例えば、「シェルスクリプト内の危険なコマンド実行パターンを検出する」「Pythonコード内の不審なネットワーク接続を識別する」「xxxというセキュリティスキャンツール、リスクアセスメントツールを呼び出す」というような具体的な指示を与えることが可能です。複雑なリポジトリに対して、まず全体を俯瞰した後に怪しい部分を詳細に分析するという段階的なアプローチを取らせることもできます。

  3. Docker環境での安全な実行: OpenHandsはDockerコンテナ内で実行されるため、分析プロセス自体が隔離された環境で行われ、ホストシステムへの影響を最小限に抑えることができます。

このようにエージェントであることによる恩恵は大きく、しかもOpenHandsのHeadlessモードはスクリプトに組み込むのに非常に便利なので採用しました。

なぜclone時のhookにしなかったのか

post-checkout hookを利用して、git clone時に自動で行うスクリプトにするという手もありましたが、checkout時も動くスクリプトにするとcloneではないcheckoutのときに想定しないバグが出たり、そもそも毎回危険そうなリポジトリばかりをcloneする人も少ないだろうと考えたからです。

安全性の判断基準

判断基準は完全にプロンプトによって制御されます。後述しますが設定でカスタマイズ可能です。

デフォルトのプロンプト:
https://github.com/kbwo/git-safe-clone/blob/276561f5cbe508070fd822975bc110866aae29ea/git-safe-clone#L174

分析結果には必ず「This codebase is SAFE to execute」または「This codebase is UNSAFE to execute」という文字列が含まれ、これをもとに安全性を判断します。

カスタマイズ

git-safe-clone は、Git 設定を通じて様々なオプションをカスタマイズできます:

# API Keyを含む環境変数名を設定
git config --global safeclone.apiKeyEnv "YOUR_API_KEY_ENV_NAME"

# 使用するLLMモデルを設定 (モデル名は[OpenHandsのドキュメント](https://docs.all-hands.dev/modules/usage/llms)を参照)
git config --global safeclone.model "your_preferred_model"

# ランタイムDockerイメージを設定
git config --global safeclone.runtimeImage "docker.all-hands.dev/all-hands-ai/runtime:0.28-nikolaik"

# OpenHandsコンテナイメージを設定
git config --global safeclone.containerImage "docker.all-hands.dev/all-hands-ai/openhands:0.28"

# カスタムセキュリティ分析プロンプトを設定
git config --global safeclone.prompt "Your custom security analysis prompt"

# 安全マーカーを設定(LLMの出力で安全と判断するための文字列)
git config --global safeclone.safeMarker "This codebase is SAFE to execute"

# 危険マーカーを設定(LLMの出力で危険と判断するための文字列)
git config --global safeclone.unsafeMarker "This codebase is UNSAFE to execute"

# 大きなリポジトリを分割する際の最大チャンクサイズを設定(行数)
git config --global safeclone.maxChunkSize "50000"

# 分析前に実行するカスタムスクリプトを設定
git config --global safeclone.preAnalysisHook "/path/to/your/script.sh"

実際の使用例

実際に git-safe-clone を使ってみましょう。安全なリポジトリと危険なリポジトリの両方をテストしてみます。

テスト時のLLMモデルはopenrouter/deepseek/deepseek-r1:freeを使っています。

安全なリポジトリのクローン

git safe-clone https://github.com/kbwo/dotfiles

このコマンドを実行すると、リポジトリがクローンされ、OpenHandsによる分析が行われます。分析の結果、安全と判断されると以下のようなメッセージが表示されます:

危険なリポジトリのクローン

テスト用に作成した危険なリポジトリをクローンしてみます:

git safe-clone https://github.com/kbwo/git-safe-clone-test-dangerous-repo

このリポジトリには意図的にPython製の危険なコードが含まれています。(環境を壊さず、システム情報を架空の外部ドメインに送信する趣旨のコードですが、一応公開していません。)分析の結果、危険と判断されると以下のようなメッセージが表示され、クローンしたディレクトリは自動的に削除されます:

さらに、一見普通のライブラリに見えながらも、難読化された危険なコードが含まれているリポジトリでもテストしてみました:

git safe-clone https://github.com/kbwo/git-safe-clone-test-stealth-js

このリポジトリには一見ライブラリに見える画像処理関連のコードと、それに混ざって難読化された危険なコードが含まれています。(このコードも一応公開していません。):

一見問題ないように見えるコードでも、難読化された危険なコードを混ぜていると危険性が見つかり、リポジトリのディレクトリは削除されました。

注意点

初回の分析は非常に遅い

OpenHandsのコンテナ、及びOpenHandsのruntime用のコンテナを実行する仕組みのため、キャッシュがない場合は OpenHands の Docker イメージの pull も行われるため、分析作業が始まるまで時間がかかります。また、それがなくてもこのツールが行う処理の性質上多少時間はかかってしまいます。

ツールの弱点

  • (現状は)分析がgit cloneしたあとに行われる
    • 処理内容からしてgit cloneする前でもやりようはあると思うので今後改善していきたいです
  • 全面の信頼はおけない
    • 当然ですがこのコマンドを通してクローンができればコードを全面的に信頼して良いわけではありません
    • またこのツールのプロンプト、処理内容が万全な完成度と言えるほどのテストは行われていません
  • ghqコマンドとのインテグレーションをサポートしていない
    • 私自身がghqユーザーなのでなんとかしたいです...

まとめ

git-safe-clone を使えば、未知のリポジトリをクローンする際のセキュリティリスクを軽減できます。LLM を活用したコード分析により、悪意のあるコードや安全でないコードを含む可能性のあるリポジトリからユーザーを保護します。

オープンソースの世界では、多くの素晴らしいプロジェクトが共有されていますが、同時にセキュリティリスクも存在します。git-safe-clone がそのリスクを少しでも軽減し、より安全なオープンソース体験の一助となれば幸いです。

リポジトリはこちらです:

https://github.com/kbwo/git-safe-clone

ぜひ試してみてください。フィードバックやコントリビューションもお待ちしています。

Discussion