Snykの導入に際して検討しておくといいこと~見取り図~

https://qiita.com/advent-calendar/2023/snyk

Advent Calendarに初参加です!
Snykの導入ステップから具体的なスキャンした際のTipsといった内容について記載しています。
皆さんの参考になれば幸いです。

# 1. Snykを段階的に導入していくことの指針
Snykを導入する際には段階的に取り入れていくことがおすすめです。
現在の組織における段階を考慮しつつ、以下の４つのフェーズのどこにいるかを確認しましょう。
1. 可視化フェーズ
2. 新たな問題を防止するフェーズ
3. バックログ修正フェーズ
4. セキュリティ最適化フェーズ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/470a59c8-32a0-63b9-dc8e-98509c392432.png)




## 1-1. 可視化フェーズ
#### 目標: 
セキュリティ体制を可視化します。
#### アクション:
* IDEにSnykプラグインをインストールし、コードコミット前にセキュリティチェックをします。
* プロジェクトをインポートし、リスクプロファイルの評価を行います。
* 手動修正を試し、Snykの展開方法を試します。
* プロジェクトの脆弱性に対する優先順位付け計画を作成します。

## 1-2. 新たな問題を防止するフェーズ
#### 目標: 
開発者がコードに新しい問題を持ち込むのをブロックします。
#### アクション:
* Snykをゲートキーパーとして設定し、プルリクエスト/ビルドをブロックする条件を指定します。
* 重大度の高い問題に対して、プルリクエストを失敗させるアプローチから始めます。

## 1-3. バックログ修正フェーズ
#### 目標: 
技術的セキュリティ上の負債を削減し、追加の自動化を導入します。
#### アクション:
* 開発者の時間を問題の修正に充てます。
* 自動修正PRの有効化やSnykによるJiraチケットの作成を検討します。
* 進行状況を平均修正時間でモニタリングします。

## 1-4. セキュリティ最適化フェーズ
#### 目標: 
運用環境の監視を継続し、開発者が早期テストを行うことでプロセスを改善します。
#### アクション:
* 開発者の早期テストを奨励します。
* 新製品や機能の開発にSnykによるセキュリティテストを組み込みます。

# 2. ワークフロー
ワークフローは以下の４つの段階に分けられます。
それぞれにおけるSnykの活用方法を見ていきましょう。

1. Code
2. Git Repository
3. CI/CD
4. Production

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/5a4680e1-9c91-e106-e0fc-f43b7e0feae9.png)


## 2-1. Code
コーディングの段階では、シフトレフトのセキュリティとして、IDEにSnykプラグインの導入を試みます。
* コードをリポジトリにプッシュする前にオープンソースの問題をチェックする
* コードをリポジトリにプッシュする前に、コードのセキュリティと品質の問題をチェックする
* Snyk の結果を使用して問題を修復または無視するかを決定する

## 2-2. Git Repository
GitへコードをPushし統合する段階では、ゲートキーパーの導入を試みます。
* コードをリポジトリに追加する前にセキュリティチェック（ゲートキーパー）を実施する
* Snyk が特定した問題に利用可能な修正がある場合、プルリクエストを自動的に作成する
* 使用中の依存関係に利用可能なアップグレードがある場合、プルリクエストを自動的に作成する

## 2-3. CI/CD
コードがリポジトリにコミットされると、CI/CDによりソフトウェアのビルドがトリガーされます。
Git Repositoryでのプッシュとの違いはフィーチャーブランチではなく、メインブランチにコードをマージしている点です。
本番環境で実行されているコードのスナップショットを監視し、問題を検出した場合はアラートを通知するようにします。
* 追加の自動化として、重大度の高い問題があった際に本番環境へのビルド前にコードを監視する

## 2-4. Production
優先順位をつけてSnykで検出した問題を解決していきます。コードは継続的に監視し、新たな脆弱性が発見された際には通知が届くように設定します。
* 修正内容としてはアップグレードに関連したものがありますが、依存関係や内部・外部アプリケーションに影響するかを考慮する必要があります
* 継続的なモニタリングを実施します


# 3. Snyk組織の構成方法
Snykでは、「Group」→「Organizations」→「Projects」というストラクチャ構造となっています。
「Group」はOrganizationを束ね、グループのポリシーを設定できます。
「Organizations」は外部との統合設定やその他のOrganization内でのポリシー設定をします。
「Projects」は関連するメタデータを含み、Snykがテストするコンポーネントの対象となります。

ここでは「Organizations」をどのように構成するかについて見ていきましょう。
下記の４つの管理方法が考えられますので、各ポイントを考慮して、最適なOrganization構成方法を検討します。

1. 「チームごと」
    * チームごとにプロジェクトを作成することで、進捗状況に合わせたSnykレポートの出力が容易になります。
    * 複数のチームが１つのアプリケーションを作成する場合には、管理が複雑になる可能性があります。

2. 「アプリケーションごと」
    * 同じアプリケーションに関わるチームが一緒になってプロジェクトを管理します。
    * Snykレポートはアプリケーションのセキュリティに焦点を当てたものになります。
    * アプリケーションのスコープを明確化し、所属させるチームの対象を選ぶ必要があります。

3. 「環境ごと」
    * 例えば本番環境や開発環境に基づいてプロジェクトを作り、管理します。
    * プロジェクトやアプリケーションの数が増えすぎると、管理が難しくなります。

4. 「製品ごと」
    * 「チームごと」と「アプリケーションごと」の中間として、製品ごとにプロジェクトを作成します。
    * 製品のセキュリティ体制に関するSnykレポートも管理しやすくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/7263f23c-0d95-a8b7-5507-a9ed68e2c427.png)


# 4. IDEへの導入
まずはIDEへの導入をしましょう。

VS Codeへのプラグインを導入します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/657ec430-3b32-9033-637b-cde67835887d.png)

「Trust workspace and connect」からSnykへの認証を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/06f4b6ee-b088-c024-5522-22e14f06190f.png)

WEBブラウザで認証を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/b0b8a53a-2d8b-323e-d2a1-2cd4468ccfd5.png)

認証されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/ce14b6c2-d563-9ac4-4b03-347f78985754.png)



# 5. 検証_1-1可視化フェーズ
1-1可視化フェーズとして、まずはIDEへの手動修正を実施していきます。
今回は、数多くの脆弱性を含むハンズオン用のJuice-Shopアプリケーションを利用して試していきます。

> Github：https://github.com/snyk-japan/juice-shop

VS Codeにソースコードをクローンして、Snykスキャンをかけていきます。

:::note info
スキャンするフォルダについては、設定の「Trusted Folders」に追加することで対象とすることができます。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/38497779-45f2-f957-8ec0-8a26cbc9c42a.png)


:::note info
IDEでのスキャンを実行するためにSnyk Portal「Settings」のSnyk Open SourceやSnyk Code、Snyk IaCの有効化「Enable」を実施することが必要です。
:::

* Snyk Open Source
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/4d201743-6d21-2dd6-bb41-51658963839e.png)

* Snyk Code
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/b6481e87-705d-3162-f3af-b575349f1446.png)

* Snyk IaC
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/acdad704-becb-c54d-48e6-f12a0cc24db5.png)


# 5-1 IDE(VS Code)でのスキャン結果
VS Codeではセキュリティ面で以下３つのスキャンを実行できます。
① Open Source Security
② Code Security
③ IaC Security
また、コード品質のためのスキャンも実行できます。
④ Code Quality

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/a3535c51-db43-54a5-1443-ed09eda27150.png)

:::note info
Critical/High/Medium/Lowの４種類の重大度があります。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/b8d28368-92fd-ccf3-b764-6afd946750c3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/83fec88f-cce5-e033-0037-6bbf560680ae.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/733cd9a5-e2f8-2c69-ad25-2795d9bdec47.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/b146d6ea-247d-420f-3ad3-69aafaf1e0cf.png)



# 5-2 IDE(VS Code)でのスキャン結果-詳細
① Open Source Security
スキャン結果から、package-lock.jsonでのOSSバージョンを修正する箇所を特定します。

（「OPEN SOURCE SECUITY」の該当箇所をクリックしてもJSONファイルが開かなかったので、手動でJSONファイルを開きました。）

:::note warn
警告
バージョンの変更には互換性に注意してください。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/abb23284-81ab-b059-a067-181e55eedf53.png)

② Code Security
スキャン結果の該当箇所をクリックすると、該当箇所へ飛ぶことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/59814fa5-0248-0886-602b-30c1ccb3e6b8.png)
何種類か修正方法について具体例があるのはいいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/f5b28802-3a36-b4c5-2f7b-40a045457af4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/7faa3746-2fe8-551c-b0aa-0d2548df14eb.png)

③ IaC Security
スキャン結果の該当箇所をクリックすると、該当箇所へ飛ぶことができます。
「Remediaction」に修正内容の方針が示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/a9aa36a5-1183-87c4-eaa1-4ff95d8e2a99.png)

④ Code Quality
スキャン結果の該当箇所をクリックすると、該当箇所へ飛ぶことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/20bee0e9-4f27-82d8-1270-9a9d694830c9.png)

# 5-3 Snyk CLIでの検証
Snyk CLIを使用することで、スキャンすることも可能です。


| プロダクト | 説明 | CLIコマンド |
|------------|------|-------------|
| Snyk Open Source | プロジェクトが利用している依存先オープンソースライブラリの脆弱性を監視。 | `snyk test`, `snyk monitor` |
| Snyk Code | 静的コード解析を行い、コード内の脆弱性や埋め込まれたクレデンシャルを検出。 | `snyk code test` |
| Snyk Container | Dockerfile内のシェルコマンド等の脆弱性や、依存先ベースイメージの脆弱性を検知。 | `snyk container test`, `snyk container monitor` |
| Snyk Infrastructure as a Code | IaCコードをクラウドプロバイダーのベストプラクティスと比較し、設定上の不備を検知。 | `snyk iac test` |

* snyk testコマンドの実行例
CLIでの実行結果は文字でズラッと表示される形式のため、Snykプラグインの結果の方が見やすいですね。その他コマンドも同じような表示画面でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/0af229f1-54ed-c2dc-a5a4-a9ff2d758bd8.png)



**Snyk testコマンドの使用について**
snyk testは開発の早い段階での脆弱性検出に、snyk monitorはプロジェクトの脆弱性を継続的に監視するために使用します。

:::note info
**snyk testコマンド**
snyk testコマンドは、開発プロセスの中で脆弱性を発見するために使います。
特に、プロジェクトのビルド時や、プルリクエストの作成時に実行すると効果的です。
このコマンドは、プロジェクトに含まれる依存関係を分析し、既知のセキュリティ上の脆弱性を検出します。
検出された脆弱性は、その場で修正することが推奨されます。
CI/CDパイプラインに統合することで、自動的にコードの脆弱性をチェックし、セキュリティ上の問題がある場合にはビルドを失敗させることができます。
:::

:::note info
**Snyk monitorコマンド** 
snyk monitorコマンドは、プロジェクトの脆弱性情報をSnykに送信し、継続的な監視を行います。
これにより、プロジェクトの脆弱性状況を時間経過とともに追跡できます。
通常、プロジェクトが安定した段階（例えば、メインブランチにマージする時など）で使用します。
これにより、プロジェクトの最新状態をSnykに記録し、新たに発見された脆弱性に対しても通知を受け取ることができます。
monitorコマンドは、開発者が手動でプロジェクトの状態を定期的に更新する必要がないため、効率的なセキュリティ監視が可能になります。
:::

# 5.4 GitHubでのSnyk Monitor
公式ドキュメントによると以下の３ステップでSnyk CLIの導入をします。
1. **脆弱性の露出（snyk monitorを使用）**
   - 最初の段階では、`snyk monitor`コマンドを使用してプロジェクト内の脆弱性を露出し、それらを監視します。

2. **Snykをゲートキーパーとして利用（snyk testを使用）**
   - 次に、`snyk test`コマンドを利用して、CI/CDプロセスにおけるゲートキーパーとしてSnykを使用します。これにより、ビルドプロセス中に潜在的な脆弱性を検出し、セキュリティ上の問題がある場合にビルドを停止します。

3. **継続的監視（snyk testとsnyk monitorの併用）**
   - 最終段階では、`snyk test`と`snyk monitor`を併用して、プロジェクトの継続的な監視を行います。これにより、新たに発見された脆弱性に迅速に対応し、セキュリティ状況を継続的に改善します。

ここで、先ほどのコマンドの適用範囲を見てみます。
| プロダクト  | CLIコマンド |
|------------|-------------|
| Snyk Open Source | `snyk test`, `snyk monitor` |
| Snyk Code | `snyk code test` |
| Snyk Container | `snyk test`, `snyk monitor` |
| Snyk Infrastructure as a Code | `snyk test` |

:::note info
すべてをmonitorコマンドで監視したいものの、プロダクトが対応しているわけではありません。
そこで、「**continue-on-error: true**」を設定して、build自体が失敗しないようにします。
:::

今回はGitHubとの連携時のスキャンを実行するようにします。
GitHub Actionsを利用して、「.github/workflows」配下にsnyk.ymlファイルを作成します。

```yml:snyk.yml
name: Example workflow using Snyk
on: push
jobs:
  security-dotNET:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: Run Snyk to check for vulnerabilities
        continue-on-error: true
        uses: snyk/actions/dotnet@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
          command: monitor
  security-node:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: Run Snyk to check for vulnerabilities
        continue-on-error: true
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
  security-docker:
    runs-on: ubuntu-latest
    steps:
      - name: Run Snyk to check Docker image for vulnerabilities
        continue-on-error: true
        uses: snyk/actions/docker@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          image: your/image-to-monitor
          command: monitor
  security-iac:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run Snyk to check Kubernetes manifest file for issues
        continue-on-error: true
        uses: snyk/actions/iac@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --scan=resource-changes


```

:::note warn
警告
SnykのToken(API Key)は平文で直書きせずに、GiuHub上のシークレットに保管しましょう。
:::

GitHub Action側でスキャン結果を確認することができます。
`snyk test`と`snyk monitor`の違いがGitHub Actionの結果を見る場合、あまり関係がないかもしれないです。まだこの恩恵を受けている段階ではないため、推測となりますがIDEやSnyk Portalでの使用感が変わるのでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/7f52d121-8e7a-f79c-56a9-b34748ffb3e9.png)



# 検証_1-2新たな問題を防止するフェーズ

1-2新たな問題を防止するフェーズとして、Snykをゲートキーパーとして導入します。
今回はGitHubとの連携時のスキャンを実行するようにします。
GitHub Actionsを利用して、「.github/workflows」配下にsnyk.ymlファイルを作成します。

```yml:snyk.yml
name: Example workflow using Snyk
on: push
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
```

GitHub Actionの結果が出てきました。
今回は脆弱性が検知されたため、Failしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/9022a58a-b2a0-b372-94a3-4f90198f20c5.png)

```yml:snyk.yml
name: Example workflow using Snyk
on: push
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=critical
```

:::note info
critical以上の場合のみFailするようにするには、argsで「**--severity-threshold=critical**」と指定します。
:::

Failの発生を防ぐためにはゲートキーパーの導入の前までにある程度の脆弱性を解消しておく必要があります。
また、スキャン結果のFail基準を検討する必要があります。

# 検証_1-3. バックログ修正フェーズ
Snykにより検出した脆弱性を修正するための自動修正プルリクエストを作成することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/830070ea-4b42-fe4b-733d-98c1b289451d.png)

プルリクエストの内容例
コンフリクトを起こす場合があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/61cb0e07-76a3-2a2d-bbdf-88da47ce17d5.png)

:::note warn
警告
パッケージのバージョンを上げる場合にはアプリケーションの互換性等を確認する必要があり、慎重に検討する必要があります。
:::

JiraやSlackとの通知統合も可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/59b7e193-06c5-90ef-a1fd-be4112ba4b95.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/8ca6c207-8703-0e71-fada-554f719cc1cc.png)


# 検証_1-4. セキュリティ最適化フェーズ
SSVC等を参考に、脆弱性を発見した際にどのような優先順位に従って対応していくかといった方針を決定することで最適化を図る必要があります。
すべての脆弱性に全力で対応することは難しく、脆弱性をゼロにするといったことはコスト・労力ともに見合ったものではないという認識を念頭に置く必要があると思います。
継続的な対応ができる範囲で運用体制を確立することが求められます。

少なくともCriticalを対応したいと思いましたが、自動修正プルリクエストで表示されないCriticalもあるようですので、脆弱性の脅威度に基づいて検討する必要がありそうです。

# おわりに
以上で記事を終わります。
音楽が好きで、公式ドキュメントの読みこみやブログ記事作成時には欠かせません。
最新のイヤホンあたるといいな～。

# 参考サイト
https://training.snyk.io/courses/ways-to-use-snyk

https://docs.snyk.io/