今日から始めるセキュリティシフトレフト on AWS ①Git Hooksでシークレット情報を守る

# はじめに
昨今、システム構築におけるセキュリティの重要性は依然と比べて高まってきている。
AWSでも様々なマネージドサービスでセキュリティを担保してくれているが、マネージドサービスの利用方法も含めたソフトウェア寄りのセキュリティは責任共有モデル上、ユーザサイドの責任となる。

https://aws.amazon.com/jp/compliance/shared-responsibility-model/

本記事では、ソフトウェアのセキュリティを早期から効率よく高める＝セキュリティシフトレフトの方式を考察していく。

第1回は、システム実装の入口となる、Gitにおけるセキュリティ向上を行う。

後工程のセキュリティは、最悪、プロダクション環境へのデプロイをしなければ守ることができるが、誤ってGitに対してシークレットをCommitしてしまうと、即座に悪用されるリスクに晒されることになる。

Commit前にこういった状況を回避するための仕組みを紹介していく。

# Git Hooksを活用しよう
## Git Hooks概要
Git Hooksは、その名の通りGit操作に対するフック機能だ。
pre-commitフックを活用することで、危険な情報のCommitを防止ができる。

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF

Git Hooksについては以前、TerraformのTFLintに関する記事でも取り上げたことがある。
これはインフラ構築に関するセキュリティシフトレフトと言える。

https://qiita.com/neruneruo/items/8feaa5a8e45bb651fdff

## フレームワーク導入による効率的な管理
Git Hooksは若干クセがあって使いづらい。
これを効率よく管理するためのフレームワークが存在する。

検索エンジンでの検索で上位に引っかかってくるのはpre-commit(フック名ではなくてこういうソフトウェア名)だが、Pythonで作られていて、Pythonやpipのインストールが必要になる。開発環境は人それぞれであるため、OS以上に環境依存の仕組みの導入はできれば避けたい。

ということで、リポジトリよりも更に前段階のセキュリティ向上については、シングルバイナリで動作するツールを導入する方がより簡単に間口を広げられると考える。特定言語を導入すると、言語や依存パッケージのアップデートで余計な手間がかかることになるため、できるだけシンプルに導入できた方が良いだろう。

ということで、今回はLefthookというフレームワークを使用する。

Lefthookのインストールについては、公式のガイドを参考にしてもらえれば良い。

https://github.com/evilmartians/lefthook/blob/master/docs/install.md

手動でインストールする場合は、以下の記事が参考になる。

https://qiita.com/neruneruo/items/327ee9c3d0e81bd26027

Lefthookをインストールした後は、対象のリポジトリをinitなりcloneした後に以下のコマンドを実行しよう。

```shell-session
$ lefthook install
```

これを行うことで、そのリポジトリの./.git/hooks/pre-commitファイルに、Lefthook呼び出し用のスクリプトが追記される。

## Lefthookから呼び出すツールの選定

さて、Lefthookの準備が整ったら、今度は呼び出すツールの選定だ。
今回、リポジトリ内のシークレット情報の検出には、Trivyを用いる。

https://trivy.dev/

Trivyは、シークレット情報の検出だけでなく、コンテナイメージの脆弱性検査(CVEのデータベースとの照合)等も行ってくれたり、DockerfileやTerraformの脆弱性検査(静的解析)も行ってくれたりとかなり幅広く使えるため、本記事でもまた別途取り上げることになる。
今回はシークレット情報の検出にフォーカスした使い方を行う。

インストールは、Lefthook同様、公式のInsallationのページを参照。同じく手動インストールも可能だ。
こちらもシングルバイナリになっていて、余計な依存関係のインストール不要で扱いやすい。

https://aquasecurity.github.io/trivy/v0.19.2/getting-started/installation/

Trivyのインストールをしたら、```lefthook install```で作られたconfigファイルを編集する。

```lefthook.yml
pre-commit:
  parallel: true
  commands:
    trivy:
      run: trivy fs --scanners secret --exit-code 1 ./
```

さて、これで準備は完了だ。

:::note alert
```--exit-code 1```は必ず設定しよう。
これを設定しないと、Trivyが異常終了せず、警告メッセージが出力されるもののCommitが成功してしまう。
:::

リポジトリ上の適当なファイルに ```aws_access_key_id = "AKIAXXXXXXXXXXXXXXXX"```を書き加えてCommitすると、以下のように出力され、Commitがされないまま終了する。

```shell-session
$ git commit
╭──────────────────────────────────────╮
│ 🥊 lefthook v1.7.2  hook: pre-commit │
╰──────────────────────────────────────╯
sync hooks: ✔️ (pre-commit)
┃  trivy ❯ 

2024-07-15T21:20:56+09:00       INFO    Secret scanning is enabled
2024-07-15T21:20:56+09:00       INFO    If your scanning is slow, please try '--scanners vuln' to disable secret scanning
2024-07-15T21:20:56+09:00       INFO    Please see also https://aquasecurity.github.io/trivy/v0.53/docs/scanner/secret#recommendation for faster secret detection

terraform/01_main.tf (secrets)

Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)

CRITICAL: AWS (aws-access-key-id)
════════════════════════════════════════
AWS Access Key ID
────────────────────────────────────────
 terraform/01_main.tf:13
────────────────────────────────────────
  11     }
  12   
  13 [   aws_access_key_id = "********************"
  14   }
────────────────────────────────────────



                                      
  ────────────────────────────────────
summary: (done in 1.05 seconds)       
🥊  trivy
$ 
```

LefthookはGlobフィルターや、除外するための設定などが豊富にある。
.tfのみTerraform用のセキュリティチェックを行ったり、Dockerfileのみコンテナ用静的解析を行う等も設定可能だ。詳細は以下の設定ファイルのドキュメントを確認するのが良い。

https://github.com/evilmartians/lefthook/blob/master/docs/configuration.md

これで、セキュリティシフトレフトの第一歩を踏み出すことができただろう。
AWS Summit Japan2024の「安全とスピードを両立するために ～DevSecOpsとプラットフォームエンジニアリング～」のセッションでも、

> 最後に、明⽇からやれること
> - Pre-Commit フック⼊れてない⼈は⼊れましょう!!

と言っている。
お手軽にセキュリティを高めることができるので、是非皆さんも導入を検討していただきたい。

https://pages.awscloud.com/rs/112-TZM-766/images/AWS-09_Builder-Experience_AWS_Summit_JP_2024.pdf

# チーム開発している場合はVSCode + Dev Containersでお手軽に環境を共有しよう
チームで開発していると、この手のツール類のメンテナンスが個人単位に委ねられて、アップデートをサボる人がいたり、ツールの設定を誤ったりでだんだんガバナンスが効かなくなっていく。また、人数が多くなってくると、セットアップの工数も馬鹿にできない量になってくる。
そういったケースを避けるためにも、Dev Containersで環境を共有していくのが良いだろう。

https://code.visualstudio.com/docs/devcontainers/containers

構成要素となるのは、Dev Containersの設定ファイルであるdevcontainers.jsonとDockerfileだ。

以下のような構成のディレクトリをVSCodeワークスペース配下に作っておく。

```
.devcontainer
├── Dockerfile
└── devcontainer.json
```

devcontainers.jsonのサンプルは以下の通り。
こう書いておくことで、同一ディレクトリのDockerfileのイメージを起動してVSCodeから接続することができる。

```json:.devcontainer/devcontainers.json
{
    "name": "devcontainer",
    "build": {
        "dockerfile": "Dockerfile"
    },
    "customizations": {
        "settings": {},
        "extensions": []
    },
    "remoteUser": "vscode",
    "runArgs": [
        "--userns=keep-id"
    ],
    "containerEnv": {
        "HOME": "/home/vscode"
    }
}
```

Dockerfileは以下のように書いておく。
AmazonLinux2023のコンテナは、デフォルトでかなりスリム化されていて、開発に必要なものが入っていないため、追加で色々とインストールする必要がある。

:::note warn
本来のお作法で言えば、dnfで指定するパッケージはバージョンを指定すべきなので、実際にプロジェクトで利用する場合は考慮する。今回はサンプルのため割愛している。
:::

```docker:.devcontainer/Dockerfile
FROM amazonlinux:2023.5.20240819.0

# 以降は各種設定やインストールなのでrootで実行
USER root

# タイムゾーンの変更
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# dnfの証明書の更新
RUN update-ca-trust

# 開発に必要なコマンドのインストール
RUN dnf update -y && \
    dnf install -y --allowerasing coreutils && \
    dnf install -y shadow-utils && \
    dnf install -y \
                   bash-completion \
                   git \
                   gzip \
                   jq \
                   tar \
                   sudo \
                   which \
    && \
    dnf clean packages

# vscodeユーザの作成と、sudoを可能にする
RUN groupadd -g 1000 vscode && \
    useradd -m -s /bin/bash -u 1000 -g 1000 vscode
RUN echo 'vscode ALL=(ALL:ALL) NOPASSWD: ALL' >> /etc/sudoers

# Lefthookインストール
ARG lefthook_path="/usr/bin/lefthook"
ARG lefthook_version="1.7.14"
RUN curl -L https://github.com/evilmartians/lefthook/releases/download/v${lefthook_version}/lefthook_${lefthook_version}_Linux_x86_64 -o ${lefthook_path} && chmod 755 ${lefthook_path}

# Trivyインストール
ARG trivy_version="0.54.1"
RUN rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v${trivy_version}/trivy_${trivy_version}_Linux-64bit.rpm

# お作法: rootで終わらない
USER vscode
```

このDockerfileを用いて、VSCodeでDev Containerのビルドをすることで、本記事で利用するツール類が揃うことになる。

:::note
実際は、Node.jsなりPythonなりAWS CLIなりTerraform/CDKを入れるなりしてもっと開発環境特化のコンテナにするのだろうが、本記事ではさわりの部分だけを説明するために割愛する。
:::

DockerfileでコンテナビルドしてDev Containerで接続する方法は以下を参照。

https://code.visualstudio.com/docs/devcontainers/create-dev-container#_dockerfile

これで、多人数のチームでも簡単にセキュリティシフトレフトを実現することができるようになる！

# 次回

https://qiita.com/neruneruo/items/83ed70aa286ec511f900