🍣

pre-commit: gitコミット前に認証情報など不正なコードが紛れ込んでないかチェックするツール

2024/01/28に公開

pre-commitはgitコミットを行う前に以下のようなチェックを行なって、もし違反するコードを発見した場合にgitコミットをキャンセルするツールである。

具体的には以下のようなチェックを行うことが出来る。

  • JSON, YAML, TOMLなどの設定ファイルの文法のチェック
  • 行末尾やファイル末尾に余計な空白や改行が含まれていないかチェック
  • プログラムのソースコードやドキュメント等に対してフォーマッタの適用
  • 誤ってaws_access_key_idやGCPのクレデンシャルJSONなどのセンシティブな情報が平文で含まれていないかのチェック
  • アプリケーションで使用しているライブラリ、パッケージの脆弱性診断
  • その他、任意のバリデーションスクリプトの実行

以上のように大抵のチェックが可能であるため、インフラプロジェクト、アプリケーションプロジェクト問わず常に導入したほうがいいツールである。

他にも、テストコードの実行等も行うことはできるが、git commitの度にテストが完了するまで数分〜数十分以上待たされるのはストレスが溜まるので、基本的に時間がかかるチェックはCIに任せるなど、ある程度の分業も考える必要がある。

インストール

Macのhomebrewを使用している場合、pre-commitは以下のコマンドでインストールできる。

$ brew install pre-commit

pipによるインストール方法はこちら

pre-commitではgit commitを実行する前に行うチェックを.pre-commit-config.yamlという名前の設定ファイルに定義して、プロジェクトルートに配置する。

以下は設定例。

1. OSSのhookを使用

だいたいのチェックはOSSで公開されているhookを使うだけで実施したいチェックを実現できる。

  • JSON, YAML, TOMLなどの設定ファイルの文法のチェック
  • 行末尾やファイル末尾に余計な空白や改行が含まれていないかチェック

のチェックはpre-commit-hooksを使用して、以下のような設定を記述する。

.pre-commit-config.yaml
$ cd /path/to/your-project
$ vi .pre-commit-config.yaml
# trueに設定した場合、1つでもチェックに引っかかった時点でエラー終了
fail_fast: true

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: check-json
      - id: check-toml
      - id: check-yaml
      - id: trailing-whitespace

設定を記述したら、git commit時にチェックが行われるよう、以下のインストールコマンドを実行する。

$ pre-commit install

これでgit commitを実行する際、変更にJSON、YAML、TOMLなどが含まれている場合に、hookが実行され、もしフォーマット不正な値が含まれていた場合、以下のようにエラーでcommitがキャンセルされるようになる。

使用可能なhookの一覧は公式ドキュメントで公開されている。

有名なものから草OSSまで無差別に列挙されているので、使用したいと思うhookでも本当に導入して良いか確かめてから利用するようにしたい。

2. 任意のスクリプトをhookとして実行

  • 誤ってaws_access_key_idやGCPのクレデンシャルJSONなどのセンシティブな情報が平文で含まれていないかのチェック
  • アプリケーションで使用しているライブラリ、パッケージの脆弱性診断

はセキュリティツールTrivyで実行可能だが、以下のように.pre-commit-config.yamlを設定することで、任意のコマンドやスクリプトをhookとして実行することも出来る。

# セキュリティチェックを実行するシェルスクリプトを作成
$ vi trivy.sh
#!/bin/bash

set -eu

trivy fs --clear-cache
trivy fs --scanners vuln,secret,misconfig --exit-code=1 ./
trivy fs --scanners license --exit-code=1 --severity UNKNOWN,HIGH,CRITICAL ./

# pre-commitでチェックシェルを実行するよう設定
$ vi .pre-commit-config.yaml
fail_fast: true

repos:
  - repo: local
    hooks:
      - id: trivy
        name: run trivy
        entry: ./trivy.sh
        language: system

repo: localentryにコマンドを定義することで、自作のチェックが可能になる。

なお上記設定では、どんなファイルが変更されてもTrivyのセキュリティスキャンが行われるようになっているが、以下のようにfiles属性やexclude、exclude_types属性を設定することで、特定のファイルやディレクトリをスキャン対象にしたり、除外したりすることが出来る。

(設定可能な項目は公式ドキュメントを参照)

# 例: TFLintを.tf、.tfvars、.hclファイルが変更された時のみチェック
# ただし.terraform配下は除外する
...
  - repo: local
    hooks:
      - id: tflint
        name: run tflint
        entry: ./tflint.sh
        language: system
        files: (\.tf|\.tfvars|\.hcl)$
        exclude: \.terraform\/.*$

以上がpre-commitの設定方法となる。

Discussion