Snyk Code、Snyk Open Sourceを使って脆弱性診断してみた

# 1. はじめに
社内でSnykに関するハンズオンの案内がありました。私が勉強不足でSnykが初耳であったこと、また、脆弱性スキャンツールであり、興味がある分野であったことから参加してみる事にしました。

結論を申し上げると非常に良いツールで、スキャン / 修正するだけでなく、脆弱性に関するノウハウを蓄積するのにも優れたツールだと思います。

本記事はハンズオンの中で許諾を得て投稿しています。Snyk株式会社の皆様、有難うございました。

# 2. 読むと参考になる方
- Snykという単語が初耳の方
- 静的解析ツールに興味がある方
- 脆弱性スキャンに興味がある方

# 3. この記事のゴール
- Snykの概要を理解する
- Snyk（無償版）を導入し、コードのスキャン / 修正ができるようになる

# 4. 前提知識
- Gitの使い方
- Githubの使い方

# 5. Snykとは
![Snykのロゴ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/d937cab8-74f0-c54c-95d4-9f85814c464a.png)

https://go.snyk.io/jp.html

> Snyk（スニーク）は、安全な開発を迅速に行うことを支援しています。コードやオープンソースとその依存関係、コンテナやIaC(Infrastructure as Code)における脆弱性を見つけるだけでなく、優先順位をつけて自動的に修正します。Gitや統合開発環境(IDE)、CI/CDパイプラインに直接組み込むことができるので、デベロッパーが簡単に使うことができます。

Snykはスキャンを行うと検知した脆弱性にスコアを付け、深刻度が高い順に一覧表示し、それらに対する修正方法を提供します。また、脆弱性に対しSnyk Learnと呼ばれるページが用意されている場合、その脆弱性はそもそも何なのか、どんな問題を引き起こすのかなど解説してくれます。

# 6. Snykが提供する機能
クラウド環境が充実している現在、アプリケーション開発の全体像は次のケースが多くなってきているようで、プロジェクト固有コードのレビュー、修正だけでも時間がかかると思いますが、それ以外のライブラリに80%もの脆弱性が含まれているようです。

また、人間はミスをする生き物ものですから、ヒューマンエラーによる設定ミスは必ずと言って良いほど発生します。コードに含まれる脆弱性以外の問題も無視はできないため、かなりの工数を削られることになるかと思います。Snykが次の1~4までをカバーすることで、工数の削減を実現してくれるようです。

|   #   | カテゴリー            | 説明                                            | コード全体に対する割合 | 対応するSnykの製品     |
| :---: | :-------------------- | :---------------------------------------------- | :--------------------: | :--------------------- |
|   1   | App Code              | プロジェクト固有のコード                        |         10~20%         | ***Snyk Code***        |
|   2   | Open Source Libraries | 脆弱性の80%は依存関係で見つかる                 |         80~90%         | ***Snyk Open Source*** |
|   3   | Containers            | コンテナには多数のLinuxパッケージ。脆弱性も継承 |           -            | Snyk Container         |
|   4   | IaC                   | 脆弱性の発生原因 1位: 設定ミス                  |           -            | Snyk IaC               |

次にSnykを活用できるタイミングです。CLIも提供されており、開発の様々なフェーズで使うことができるようです。

|   #   | フェーズ            | 活用方法                                                                            |
| :---: | :------------------ | :---------------------------------------------------------------------------------- |
|   1   | コーディング        | 開発しながらスキャン                                                                |
|   2   | SCM(ソース管理)     | ・チェックイン・マージ時にスキャン<br>・スキャン / 自動修正<br>・ビルド時にスキャン |
|   3   | CI / CD             | ビルド連携した検出・修正                                                            |
|   4   | 本番環境 / クラウド | 脆弱性検出、アラート発出                                                            |

# 7. 今回のハンズオンの学習領域
私が参加したハンズオンでは上表の1, 2をカバーする内容でした。ここからは実際に環境を構築し、***Snyk Code***, ***Snyk Open Source***でスキャン / 修正するまでを実施してみます。

# 8. 全体の流れ
作業は次の流れで実施します。

1. 環境構築
   - パブリックなGithubアカウント作成
   - Git clientの導入
   - Snykアカウント（無償版）の設定
     - Snykアカウント（無償版）の作成
     - Snyk Codeを有効化する
2. Snyk UIでスキャン(ブラウザベース)
   - Snyk Codeでスキャンする
   - Snyk Open Sourceでスキャンする
3. Snyk CLIでスキャン(コマンドベース)
   - Snyk Codeでスキャンする
   - Snyk Open Sourceでスキャンする

# 9. 環境構築
## 9.1. Githubアカウント作成
「2. Snykアカウント（無償版）を作成する」でGithubアカウントを紐づけます。既にパブリックなアカウントをお持ちであればそのまま進んでください。

## 9.2. Git clientの導入
Githubアカウントを既にお持ちの方は問題ないかと思います。GithubアカウントとGit client共に必要な場合はここで準備しておいてください。

## 9.3. Snykアカウント（無償版）の設定
GithubアカウントがあればSnykアカウントを作成する手間が省け、すぐに使えるようになります。

### 9.3.1. Snykアカウント（無償版）の作成

1. 下記へアクセスし、「GitHub」を選択します。

https://app.snyk.io/login

![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/964d2678-03e5-fb78-d092-27c18abf2eb5.png)

2. 認証情報を入力すると下記が画面が表示されるので許可します。
![Snyk連携1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/70ff04c8-c78f-86f8-846d-5a6e8e818b2a.png)

3. 製品に関するアップデートを取得する場合はチェックします。
![製品情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/44b01247-71bc-2635-d4a1-1d5f24cd20a1.png)

4. Githubを選択します。
![Githubを選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/11a027f1-d05f-fe32-b7cf-36e8e75be204.png)

5. どの可視性を持つリポジトリへアクセスするか指定します。「Public and private repos」のまま「Continue」を押下します。
![アクセス権限設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/9d5a1907-7cdd-cfdd-d704-f6029ca27cb0.png)

6. 最後に権限設定画面が出ますので許可します。
![Snyk連携2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/fac37869-e335-cbbf-c3b0-9f1a41167c8d.png)

### 9.3.2. Snyk Codeを有効化する
1. [画面右上の歯車アイコン] -> [Snyk Code] -> [Enabled] -> [Save changes]を実行し、Snyk Codeを有効化します。
![SnykCode有効化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/6e5eb8c0-8457-e70a-8ec8-730e6d036665.png)

# 10. Snyk UIでスキャン(ブラウザベース)
## 10.1. Snyk Codeでスキャンする
Snyk Codeは静的解析を行うツールです。こちらで検出された脆弱性は自動修正の対象にはなりません。

### 10.1.1. スキャンを実行
1. 下記サンプルコードをforkします。脆弱性スキャンはこのコードに対して行います。

https://github.com/snyk-japan/juice-shop

2. Snykの画面に戻り[Project]を押下。インポート対象のプロジェクト、今回は先程forkしたjuice-shopを選択し[Import and scan]を押下します。
![サンプルコードをインポート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/fa2b19c3-72de-1a10-d1e0-8bca53aa038b.png)

### 10.1.2. スキャン結果を確認
インポートと同時にスキャンが走り、しばらくすると終了します。その後、「Code Analysis」を選択すると静的解析の結果を表示します。
![CodeAnalysis.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/6651f21f-4edf-4a2d-0c9e-e605c17e1092.png)

### 10.1.3. スキャン結果の見方
Snyk Codeでスキャンした結果は下記項目を示してくれます。
- 検出された問題の総数
- 脆弱性の深刻度
- CWE(Common Weakness Enumeration: 共通脆弱性タイプ)
- 脆弱性の種類
- 脆弱性の概要
- 脆弱性の存在するファイル名 / 行
- Snyk Learnへのリンク(***提供されている場合***)*1
- Ignoreボタン*2
*1: 修正方法について学ぶことができます
*2: 結果から脆弱性を除外することができます

また、画像左に示しているペインではスキャン結果を深刻度、スコア、状態、言語、脆弱性でフィルターすることも出来ます。
![SnykCodeスキャン結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/373e0e79-49e2-cf07-6ed3-f7f006d12750.png)

### 10.1.4. 脆弱性の詳細
画像の[Full Details]ボタンで関連するコードをハイライトし詳細を確認することができます。また、[Fix analysis]タブとスキャン結果一覧にあるSnyk Learn(Learn about this type of vulnerability and how to fix it)というテキストリンクを合わせて閲覧すれば、脆弱性の内容を深く理解し、修正方法を学ぶことができます。
![脆弱性詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/eb1fc6a7-a595-8bbe-ad4d-3c96185393b4.png)

## 10.2. Snyk Open Sourceでスキャンする
Snyk Open Sourceはソフトウェア構成解析ツールです。オープンソースが含む脆弱性とライセンスポリシー違反を検出、修正、管理することができます。

### 10.2.1. スキャン結果を確認
スキャンはインポート時にされているため結果を確認しましょう。画像のようにpackage.jsonが複数ある場合、「frontend/」ではない方を選択します。画像の例では下のファイルを選択します。
![package.jsonを選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/a2e69c48-eb41-9ecf-1a2b-d1e7644a4203.png)

### 10.2.2. スキャン結果の見方
修正が提供されているもの、一部提供されているもの、されていないものが一覧表示されます。検出された個々の問題にある「Show more detail」を押下すると詳細を表示し、下記項目を示してくれます。
- Introduced through: 脆弱性の混入元であるパッケージ(推移的依存パッケージからの混入の場合は、マニフェストファイルで宣言されたパッケージが表示されます)
- Detailed paths and remediations: 混入元の依存パッケージまでのパスと、修正方法
- Overview: 脆弱性についての概要
- Exploit maturity: 攻撃可能性 (PoC=実証コードの有無など、攻撃される可能性の程度)
- Links to CWE, CVE and CVSS Score: CWE と CVE へのリンク、CVSS スコア
- その他
![SnykOpenSourceスキャン結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/6f4223c8-fc5a-75a7-81ca-925f8c2557f7.png)

### 10.2.3. 自動修正する
1. Githubを連携済で、Snyk Open Sourceで検出された脆弱性に対して修正が提供されている場合はプルリクエストを通じて自動修正が可能です。ここでは「Prototype Pollution」の脆弱性を修正してみることにします。"Fix this vulnerability" ボタンを選択します。
![Fix this vulnerability.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/54b585c4-ae3b-c00a-850a-ea3cf585e46c.png)

2. 先程の結果に対しそれぞれチェックボックスが設けられた状態で一覧表示されます。修正を適用したいものを選択し、画面下部の[Open a Fix PR]を押下します。
![修正可能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/24267158-6009-83cf-bb19-0315de7bcd7b.png)
![一部修正可、修正不可.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/3d7a83fa-703d-733b-2471-1f25d4d5b7f3.png)

# 11. Snyk CLIでスキャン(コマンドベース)
## 11.1. 環境構築

次の順で進めていきます。
1. Alpine Linuxの導入
2. Snyk CLIを導入

ハンズオンの事前準備でAlpine Linux*1の導入があったため、それに基づいて実施していきます。別のディストリビューションでも良いと思いますので、その際はコマンドを適宜読み替えてください。

Alpine Linuxのパッケージ管理はapkですのでyumやaptとは違った使い方になります。説明を行いながら実施するため、Alpine Linuxを触ったことがない方も安心してトライいただけます。

### 11.1.1. Alpine Linuxの導入
私はWSL2で導入しました。WSLを使ったことがない方は下記を参照してWSLを構築し、Microsoft Storeで"Alpine WSL"で検索してインストールしてください。

https://devlog.grapecity.co.jp/wsl-2-setup/

![MSストア Alpine LInux .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/0fab0c6c-e2b0-062d-ae05-505d997eb584.png)

インストール後、起動して下記画像のようにユーザ名、パスワードを入力すれば導入完了です。

![Alpineインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/86f35ccf-4203-ad8d-3718-f78463e3e7ee.png)

Alpine Linuxをご存知でない方は下記をご参照ください。

https://qiita.com/ryuichi1208/items/6020cfabc92bd8153654

### 11.1.2. Snyk CLIを導入
Snykのコマンドラインツールをインストールします。Snyk CLIはnpmのパッケージとして提供されているため、npmをインストールします。既にnpmがインストールされている場合バージョン12以降であることを確認し、満たしていない場合は下記を参照いただき、npmをアップグレードしてください。

https://support.snyk.io/hc/en-us/articles/360004183317-What-version-of-Node-is-required-for-Snyk-

新規でnpmのインストールする方は次のコマンドを実行します。npmをアップグレードした方は4は不要です。
1. Alpine Linux起動時に設定したパスワードを入力し、管理者権限に移ります。
   - `su -`
2. 利用可能なパッケージリストを更新します。（パッケージのリストが更新されるだけです）
   - `apk update` 
3. libstdc++をインストールします。
   - `apk add libstdc++`
4. npmをインストールします。
   - `apk add npm`
5. Snyk CLIをインストールします。
   - `npm install snyk -g`
6. Snyk CLIがインストールされたか確認します。バージョンが1.801.0以上であることを確認してください。*1
   - `which snyk`
7. Snyk CLIを認証します。ブラウザで認証画面が出るので認証してください。これでSnyk CLIが使えるようになります。
   - `snyk auth`
![認証画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2820803/61d552c1-d234-a2d2-c098-1520bc7d454b.png)

*1: Snyk CLIがインストール出来ていない、あるいは詳細をご覧になりたい方は下記をご参照ください。

https://docs.snyk.io/snyk-cli/install-the-snyk-cli

## 11.2. Snyk Codeでスキャンする
インストールされたCLIでスキャンを実行します。次のコマンドを実行してください。

1. まずはスキャン対象のコードを落とします。別環境で落として移動させても良いです。ここではAlpine Linuxにgitをインストールしてしまいます。
   - `apk add git`
2. スキャン対象コードをクローンします。
   - `git clone https://github.com/juice-shop/juice-shop`
3. クローンしたディレクトリに移動します。
   - `cd juice-shop`
5. コードをスキャンします。私の環境では3分ほど掛かりました。
   - `snyk code test`

Snyk UI同様、スキャン結果が表示されます。

## 11.3. Snyk Open Sourceでスキャンする
インストールされたCLIでスキャンを実行します。Snyk Open SourceをCLIで実行する場合、次のコマンドが必要です。完了まで5分ほど時間が掛かりました。
- `npm intall`

上記を実行せずにスキャンすると依存性が取得できないとエラーが出てしまいます。

```
Failed to get dependencies for all 2 potential projects.
Tip: Re-run in debug mode to see more information: DEBUG=*snyk* <COMMAND>
If the issue persists contact support@snyk.io
```

スキャンを実行するには次のコマンドを実行してください。
`snyk test --all-projects`

スキャンした結果が表示されます。

# 12. 最後に
Snyk Codeは静的解析でコードに含まれる脆弱性を指摘をしてくれるため、コードの品質を高めるツールとしてだけではなく、未熟な私のようなエンジニアにとっては非常に学びの多いツールです。

経験値の多いエンジニアしか指摘出来ないものは属人的になりがちだと思いますが、コードをスキャンする事でSnykが良き先輩、レビュアーになり教えてくれます。スキャン結果から得た学びを共有出来ればチーム全体の知識レベルを底上げ出来る、そんな素敵なツールとしても使えるかと思います。

Snyk Open Sourceは実際にオープンソースの依存性の問題を解決してくれるため、かなり手間が省けます。また、Snyk Code, Snyk Open SourceのCLIを組み込むことで本番環境へデプロイするフロー内でセキュリティチェックを実行することができ、開発効率が上げることができるようです。

実際に触った感触としては学びの多いツールです。自分のコードにスキャンかけて質を高めるだけでなく、勉強するツールとしても使っていきたいと思います。

# 13. 参考リンク
- ワークショップで公開されているリポジトリ

https://github.com/snyk-japan/snyk-sca-sast-workshop