『Gitleaks』で機密情報の漏洩を防ぐ〜コマンド編〜

Gitleaksは機密情報の漏洩を防ぐためのツールです。簡単なコマンド実行を通してGitleaksの使用感を記事にしました。コマンドの使い方や実際の出力内容が分かるようになっています。
2023.06.02

はじめに

CX事業本部 Delivery部の塚本です。

Technology RadarでGitleaksが紹介されており、気になったので使ってみました。


記事で取り上げること

  • Gitleaksの基本的な情報
  • Gitleaksの導入手順
  • Gitleaksのコマンドの使い方

記事で取り上げないこと

  • GitHub Actionsでの利用方法
  • gitのhooksを利用したコミット前の自動検出: 自動コミット編参照
  • 検出結果の妥当性、信頼性など
  • 他類似ツールとの比較

Gitleaksとは

Gitleaks is a SAST tool for detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos. Gitleaks is an easy-to-use, all-in-one solution for detecting secrets, past or present, in your code.

日本語: Gitleaks は、git リポジトリ内のパスワード、api キー、トークンのようなハードコードされた秘密を検出・防止するための SAST ツールです。Gitleaksは、あなたのコードに含まれる過去または現在の秘密を検出するための使いやすいオールインワンソリューションです。

(引用元: https://github.com/gitleaks/gitleaks)

機密情報が漏洩すること防ぐ用途で利用します。

類似ツールではgit-secrets、trufflehog、secretlintなどがあります。

git-secretsについて書いてくださっている記事↓

secretlintについて書いてくださっている記事↓

Gitleaksは現在(2023/6/1)、GitHub Starが13kと多いのですが、調べてみたところ日本語記事が少なかったので今回は導入の方法を記事にしました。

導入方法

READMEに書かれている通り導入していきます。(※ Mac利用)

# MacOS
brew install gitleaks

知っておきたいコマンド

頻繁に利用するのは以下のコマンドになります。

  • detect : gitリポジトリ、ディレクトリ、ファイルをスキャンする。gitリポジトリで実行する場合、git log -p の出力をスキャンする。gitリポジトリでない場合、ローカルのファイルをスキャンする。
  • protect : gitリポジトリでのみ使用可能。ローカル環境で使用する。git diffコマンドの出力をスキャンする。

コミット履歴をスキャンする

コミット履歴をスキャンするには、detectコマンドを利用します。

シークレット情報をコミットし、その後検出できるか確かめます。

% echo "AWS_ACCESS_KEY_DUMMY = AKIAXXXXXXXXXXXXXXXX" >> .env
% git add .env
% git commit -m "add AWS Access Key"
% gitleaks detect

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

3:02PM INF 1 commits scanned.
3:02PM INF scan completed in 61.7ms
3:02PM WRN leaks found: 1

1件検出できました。

詳しい情報を見るためには、-v(—verbose) オプションを利用します。

% gitleaks detect -v

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

Finding:     ..._ACCESS_KEY_DUMMY = AKIAXXXXXXXXXXXXXXXXX
Secret:      AKIAXXXXXXXXXXXXXXXX
RuleID:      aws-access-token
Entropy:     1.021928
File:        .env
Line:        1
Commit:      18da40059beb2e6fad5625f275527473a349e341
Author:      dummu-user
Email:       dummy@gmail.com
Date:        2023-06-01T06:02:10Z
Fingerprint: 18da40059beb2e6fad5625f275527473a349e341:.env:aws-access-token:1

3:04PM INF 1 commits scanned.
3:04PM INF scan completed in 61.1ms
3:04PM WRN leaks found: 1

ファイル名、行数、コミット者、コミットIDなどが確認できます。

ローカルのファイルをスキャンする

コミット履歴ではなく、現状のローカルのファイルを確認するには --no-git オプションを利用します。

% gitleaks detect -v --no-git

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

Finding:     ..._ACCESS_KEY_DUMMY = AKIAXXXXXXXXXXXXXXXXX
Secret:      AKIAXXXXXXXXXXXXXXXX
RuleID:      aws-access-token
Entropy:     1.021928
File:        .env
Line:        1
Fingerprint: .env:aws-access-token:1

3:11PM INF scan completed in 8.94ms
3:11PM WRN leaks found: 1

特定の機密情報を検出の対象外とする(ソースにコメントを記載)

特定の情報を検出の対象外としたいケースがあるかと思います。

対象外とするためには2つの方法があります。

  • ソースにgitleaks:allow のコメントを記述する
  • .gitleaksignoreファイルを追加する(実験的な機能)

まず、ソースにコメントを追加する方法です。

コミットしても問題ないテキストを含んだファイルを作成して、検出の対象外としてみます。

% echo "AWS_ACCESS_KEY_DUMMY = AKIAXXXXXXXXXXXXXXXX" >> .env.example
% gitleaks detect -v --no-git

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

Finding:     AWS_ACCESS_KEY = AKIAXXXXXXXXXXXXXXXXX
Secret:      AKIAXXXXXXXXXXXXXXXX
RuleID:      aws-access-token
Entropy:     1.021928
File:        .env.example
Line:        1
Fingerprint: .env.example:aws-access-token:1

こちらを検出対象から外したいので、該当行に gitleaks:allow のコメントを記載します。

AWS_ACCESS_KEY = AKIAXXXXXXXXXXXXXXXX # gitleaks:allow

もう一度コマンドを実行してみると、検出されていないことが確認できました。

% gitleaks detect -v --no-git

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

3:30PM INF scan completed in 8.41ms
3:30PM INF no leaks found

特定の機密情報を検出の対象外とする(『.gitleaksignore』ファイルを追加)

※こちらは 2023/6/1 現在実験的な機能となっています。

『.gitleaksignore』ファイルを利用する方法では、コマンド実行時に出力される Fingerprint を利用します。

% gitleaks detect -v --no-git

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

Finding:     AWS_ACCESS_KEY = AKIAXXXXXXXXXXXXXXXXX
Secret:      AKIAXXXXXXXXXXXXXXXX
RuleID:      aws-access-token
Entropy:     1.021928
File:        .env.example
Line:        1
Fingerprint: .env.example:aws-access-token:1

適用方法は簡単で、『.gitleaksignore』ファイルにFingerprintの文字列をそのまま記載するだけです。

% echo ".env.example:aws-access-token:1" >> .gitleaksignore
% gitleaks detect -v --no-git

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

3:45PM INF scan completed in 8.74ms
3:45PM INF no leaks found

ただ、Fingerprintの文字列はファイル名や行数によって構成されています。コミットログの場合はコミットIDも構成要素になっています。

Fingerprint: .env.example:aws-access-token:1 # ローカル
Fingerprint: 18da40059beb2e6fad5625f275527473a349e341:.env:aws-access-token:1 # コミット

そのため、行数が変わったり変更のコミットが新しく作成された場合には、再度『.gitleaksignore』を編集する必要が出てきます。

以上から、『.gitleaksignore』を手動で管理する運用は厳しそうだと感じました。

ソースの変更内容をスキャンする

gitleaks protect を利用することで、git diff の出力をスキャンできます。

また --staged オプションを利用することで、ステージされた変更( git add された変更)をスキャンできます。

変更がない状態でコマンドを実行すると、何も検出されないことが確認できます。

% gitleaks protect

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

4:31PM INF 0 commits scanned.
4:31PM INF scan completed in 61.2ms
4:31PM INF no leaks found

機密情報を含む変更を加え、再度コマンドを実行すると検出できていることが確認できます。

% echo "AWS_ACCESS_KEY_2 = AKIAXXXXXXXXXXXXXXXX" >> .env.example 
% gitleaks protect                                              

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

4:32PM INF 1 commits scanned.
4:32PM INF scan completed in 61.8ms
4:32PM WRN leaks found: 1

さらにステージング済みの変更を検出するために、—stagedをつけて実行してみます。

% git add .env.example 
% gitleaks protect --staged

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

4:34PM INF 1 commits scanned.
4:34PM INF scan completed in 61.5ms
4:34PM WRN leaks found: 1

こちらのコマンドは公式説明にもあるように、開発者の環境でコミット前のフックで利用するイメージです。

The --staged flag should be used when running Gitleaks as a pre-commit.

日本語: Gitleaksをプレコミットとして実行する場合は、--stagedフラグを使用する必要があります。

(https://github.com/gitleaks/gitleaks/tree/master#readme)

感想

Gitleaksをお試しで使ってみました。

プロジェクトでの使用を考えると検査の自動化をする必要があるので、追加で以下の検証をしたらまたブログを書いてみようと思います!

  • huskyやpre-commitと組み合わせてコミット前の検査を自動化する
  • GitHub Actionsで自動化する

最後まで読んでいただきありがとうございました!

追記(2023/06/12)

コミット前の自動検査編のブログ書きました!