Gitリポジトリのセキュリティ強化:ベストプラクティスと信頼できないソースへの対策

シークレットを除外し、アクセスを制限し、ブランチを保護し、自動化をレビューし、未知のコードを慎重に扱うことで、Gitリポジトリを安全に保ちます。

Gitリポジトリのセキュリティ強化:ベストプラクティスと信頼できないソースへの対策

Gitリポジトリのセキュリティを確保することは、単にコードを非公開にすること以上の意味があります。リポジトリには、シークレット、実行可能なフック、サプライチェーンリスク、機密性の高い履歴、そしてリポジトリをクローンするすべての開発者に影響を与える設定が含まれる可能性があります。

適切なGitセキュリティ対策は、認証情報の漏洩、安全でない自動化、未知のソースからのコードへの偶発的な信頼を防ぐのに役立ちます。基本はシンプルですが、一貫して適用する必要があります。

シークレットがGitに到達する前に保護する

最も安全なシークレットは、リポジトリに決して入らないものです。APIキー、SSH秘密鍵、クラウド認証情報、データベースパスワード、トークン、.envファイルは、Gitから完全に除外する必要があります。

ローカルのシークレットファイルを.gitignoreに追加します:

.env
.env.*
*.pem
id_rsa
id_ed25519

.env.exampleには注意してください。このファイルは便利なことが多いですが、ダミーのプレースホルダー値を含める必要があります:

DATABASE_URL=postgres://user:password@localhost:5432/app
API_TOKEN=replace-me

「テストのためだけに」実際の値を貼り付けないでください。Gitの履歴は、後でコミットで行を削除しても古いバージョンを記憶しています。

誤ってシークレットをコミットした場合は、公開されたものとして扱います。現在のツリーから削除し、発行元のサービスで認証情報をローテーションし、履歴のクリーンアップが必要かどうかを判断します。履歴を書き換えると将来の露出を減らすのに役立ちますが、シークレットが決してコピーされなかったことを保証するものではありません。

チームはシークレットスキャンも使用する必要があります。多くのホスト型Gitプラットフォームは、一般的なトークンパターンのスキャンを提供しています。ローカルのpre-commitツールは、プッシュがサーバーに到達する前に、より早い段階でミスをキャッチできます。

関連する運用パターンについては、設定とシークレットのための環境変数の習得を参照してください。

アクセスとブランチの変更をロックダウンする

リポジトリのセキュリティはアクセス制御から始まります。人々に必要な最小限のアクセス権を付与します。コードをレビューするだけの人は、おそらく管理者権限は必要ありません。CIサービスアカウントは、おそらくブランチを書き換える権限は必要ありません。

以下の設定を定期的に確認します:

  • リポジトリ管理者と所有者。
  • 書き込みアクセス権を持つコラボレーター。
  • デプロイキーとマシンユーザー。
  • 自動化で使用される個人アクセストークン。
  • リポジトリイベントを受信するWebhook。
  • ブランチ保護ルール。

保護されたブランチは、最も有用な制御の1つです。mainのような重要なブランチでは、マージ前にプルリクエスト、ステータスチェック、レビューを必須にします。チームに非常に特別な理由がない限り、フォースプッシュを無効にします。

署名付きコミットまたは署名付きタグは、信頼性の高い環境でも役立ちます。それ自体でコードを安全にするわけではありませんが、コミットやリリースタグがチームが認識するキーによって作成されたことを証明できます。

リリースにはタグを慎重に使用します。デプロイプロセスがタグを信頼する場合、タグを作成または移動できる人を制限します。移動されたリリースタグは、監査やデプロイを混乱させる可能性があります。

信頼できないリポジトリに注意する

信頼できないソースからコードをクローンすることは一般的です。それをすぐに実行することがリスクのある部分です。Gitリポジトリには、ビルドスクリプト、パッケージのライフサイクルスクリプト、Makefile、コンテナ、CI設定、およびマシン上でコードを実行する指示が含まれる可能性があります。

何かを実行する前に、リポジトリを検査します:

git clone --no-checkout https://example.com/project.git
cd project
git log --oneline -5
git status

次に、リスクの高いファイルを確認します:

  • install.shbootstrap.shなどのシェルスクリプト。
  • package.json内のパッケージスクリプト。
  • .github/workflows/.gitlab-ci.yml、または同様のパスにあるCIファイル。
  • Dockerfileとcomposeファイル。
  • Makefile。
  • 言語固有の依存関係マニフェスト。

ランダムなREADMEからcurl | bashセットアップコマンドを実行しないでください。プロジェクトにインストーラーが必要な場合は、ダウンロードして読み、可能であれば使い捨て環境で実行します。

Gitフックは特に注意が必要です。.git/hooks/内のフックは、リポジトリをクローンするときにアクティブなフックとして通常転送されません。それは良いことです。しかし、リポジトリにはフックをインストールするスクリプトが含まれている場合があります。それらのスクリプトを実行する前に読んでください。フックはコミット、マージ、リベース、プッシュ中に実行される可能性があるためです。

未知のコードには、分離を使用します。一時的な仮想マシン、コンテナ、またはロックダウンされた開発環境は、スクリプトが不正に動作した場合の影響範囲を減らします。SSHキー、クラウド認証情報、または本番kubeconfigを、信頼できないコードに使用される環境にマウントしないでください。

リポジトリの履歴とファイルをクリーンに保つ

リポジトリが整理されていると、セキュリティはより簡単になります。大きなバイナリファイル、生成されたアーカイブ、ベンダー化されたシークレット、古い設定ダンプは、レビューを難しくし、リスクを高めます。

ローカルファイルには.gitignoreを、ファイル処理ルールには.gitattributesを使用します。例:

*.sh text eol=lf
*.png binary
*.jpg binary

プロジェクトに大きなファイルが必要な場合は、Git Large File Storageが適切かどうかを検討します。標準のGitは、巨大なビルドアーティファクトやメディアファイルには理想的ではありません。それらを直接保存すると、クローンが遅くなり、機密ファイルのクリーンアップが難しくなる可能性があります。

プルリクエストをアプリケーションロジックだけでなく、セキュリティに敏感な変更についてもレビューします。以下の点に注意します:

  • 新しい認証情報やトークン。
  • スクリプト内の新しいネットワーク呼び出し。
  • 依存関係ソースの変更。
  • 新しいCI権限。
  • デプロイスクリプトの変更。
  • 重要なファイルを隠す広範な.gitignoreの変更。

また、サブモジュールにも注意を払います。サブモジュールは外部リポジトリと特定のコミットを指します。プロジェクトで使用している場合は、サブモジュールのURLと更新を注意深く確認します。

専門家を関与させるタイミング

シークレットが公開リポジトリにプッシュされた場合、保護されたブランチが予期せずフォースプッシュされた場合、または未知のコントリビューターがCIやデプロイ自動化を変更した場合は、セキュリティエンジニア、DevOpsリーダー、またはインシデント対応責任者を関与させます。

また、リポジトリの履歴が改ざんされた疑いがある場合も支援を求める必要があります。特に企業環境では、迅速なクリーンアップよりも証拠の保存が重要になる場合があります。

Gitリポジトリのセキュリティは、規律ある信頼に帰着します。シークレットを除外し、アクセスを制限し、重要なブランチを保護し、信頼できないコードを実行する前に検査します。これらの習慣により、ほとんどのリポジトリセキュリティ問題がインシデントになる前に防ぐことができます。