Snyk を使ったアプリケーション開発のセキュリティ向上

# はじめに
　[Snyk](https://go.snyk.io/jp.html) は主に開発者向けのセキュリティプラットフォームです。Snyk を導入すると開発の速度を落とすことなくアプリケーションのセキュリティを向上させることができます。

　Snyk には以下の４つのプロダクトが含まれています。
- 自分のコード上の脆弱性をスキャンする `Snyk Code (SAST)`
- アプリケーション内で利用する OSS パッケージの既知の脆弱性をスキャンする `Snyk Open Source (SCA)`
- コンテナイメージ内に脆弱性のあるコードや OSS パッケージが含まれていないかスキャンする `Snyk Container`
- Terraform などの IaC テンプレートにセキュリティ懸念があるコードが含まれていないかスキャンする `Snyk Infrastructure as Code`
の4つです。

　本記事では、このうち Snyk Code と Snyk Open Source を取り上げ、これらを普段の開発フローの中でどのようにして活用していくか紹介します。

# 統合開発環境 (IDE) と Snyk の連携
　開発のいくつかの段階で Snyk を活用し脆弱性を発見・解消することができますが、可能であれば一番最初の段階、つまりコードを書く時点で脆弱性を解消できると嬉しいです。後の段階になるほど脆弱性解消による影響範囲の調査工数が増えるからです。
　Snyk は主要な IDE と連携させることができるため、脆弱性のあるコードを書いてしまった場合や、既知の脆弱性のあるパッケージを利用している場合は、すぐに気づくことができます。
## VS Code 上での Snyk の利用例
　本節では Visual Studio Code 上で Snyk を利用し、脆弱性を発見・解消する方法を紹介します。
　(VS Code への Snyk のインストール方法は次節で紹介します。)

例として Node.js で「Hello World」という文字列を表示させるコードを書いてみましょう。
```app.js
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
```
依存パッケージには jquery 2.2.4 を指定します。
```package.json
{
  "dependencies": {
    "jquery": "^2.2.4"
  }
}
```

VS Code に Snyk をインストールすると左サイドバーに Snyk アイコンが追加されます。
Snyk アイコンをクリックし、上記コードの検知結果を見てみます。
![DetectedBySnyk01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/a7e8a037-cc16-9782-0231-82d95e337901.png)

`OPEN SOURCE SEDCURITY` の項目で依存パッケージ jquery@2.2.4 の脆弱性が4つ見つかっています。一つだけ内容を見てみましょう。
![DetectedBySnyk02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/2ba2fd34-2b9b-fbef-a6fa-d9d0c29419ea.png)
jquery@2.2.4にはクロスサイトスクリプティングの危険があることがわかります。修正されたのはバージョン3.5.0 とのことなので、package.json を次のように書き換えてみます。
```package.json
{
  "dependencies": {
    "jquery": "^3.5.0"
  }
}
```
`OPEN SOURCE SECURITY` の項目で検知されていた脆弱性が解消されたことがわかります。
![DetectedBySnyk03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/e2dceab0-7cc9-2454-7cb6-7e4e0c72f615.png)

次に `CODE SECURITY` の項目で自分が書いたコードの脆弱性を見てみましょう。
![DetectedBySnyk04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/1b899e50-1068-a06b-ea90-8aa554689355.png)
セキュアなプロトコルを利用していないため中度(Medium)の警告が出ています。
今回は解決案も提示されているので、コードを次のように書き換えます。(http を https に書き換えています。)
```app.js
const https = require('https');

const hostname = '127.0.0.1';
const port = 3000;

const server = https.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at https://${hostname}:${port}/`);
});
```
以下の通り脆弱性が解消されました。
![DetectedBySnyk05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/ea5b01bc-b4a9-bd3a-493b-b2ed6b2a31b7.png)

　このように、普段利用している IDE に Snyk を導入することでコーディングしながら、その都度、脆弱性に気づき、それを解消できることがわかりました。
今回は Node.js の例でしたが、Python や Java を始め、様々な言語を Snyk はサポートしています。現時点でサポートしている言語の一覧は [コチラ](https://docs.snyk.io/products/snyk-code/snyk-code-language-and-framework-support)、パッケージマネージャの一覧は [コチラ](https://docs.snyk.io/products/snyk-open-source/language-and-package-manager-support) をご覧ください。
また、コードスキャンのルールについては [コチラ](https://docs.snyk.io/products/snyk-code/security-rules-used-by-snyk-code) をご覧ください。今回は説明のためにわかりやすい例を使いましたが、SQL インジェクション対策漏れや入力値のバリデーション漏れといったコード量が多くなると発生しがちな項目も網羅されています。

## VSCode への Snyk のインストール
　VSCode への Snyk のインストールは下記の手順で行います。
環境によってはうまく連携できない場合があります。その場合は手順 4番 を試してみてください。
1. Snyk Cli のインストール
VS Code は Snyk Cli を利用するので、まずは Cli ツールをインストールします。
Mac の場合、ターミナルで下記コマンドを実行します。
```
brew tap snyk/tap                                                                                              
brew install snyk
```

2.　プラグインのインストール
`Snyk Security - Code and Open Source Dependencies` をインストールします。
インストールに成功すると左サイドバーの一番下に Snyk アイコンが現れます。
![VSCodeSnyk01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/df92ad64-0b2a-5109-4e63-954b0794b5d2.png)

3.　VS Code と Snyk の連携
左下の Snyk アイコン(犬)を選択すると開く Snyk 画面で `Connect VS Code with Snyk` ボタンを押して VS Code と Snyk を連携させます。
ボタンを押すとブラウザで Snyk の管理画面が開くので認証ボタン(Authenticate)を押してください。
Authenticated 画面が表示されると成功です。
![VSCodeSnyk02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/7964928f-3f4f-8dd9-5eb1-0b69ae6cd197.png)
![VSCodeSnyk03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/7966041c-e34b-2b7c-f785-8641421700c4.png)
![VSCodeSnyk04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/9d788f5a-8e6f-d418-0bb2-2249d6e4d21c.png)

4.　正常に連携できない場合
　ブラウザで Authenticate が表示されたのに正常に連携できない場合があります。
正常に連携できていない場合とは、VS Code で何らかのプロジェクトフォルダを開いているのに Snyk のセキュリティスキャンが実行されない場合です。
その場合は、Snyk の Auth Token を直接 VS Code に設定してください。
Auth Token は Snyk の Account Settings 画面で取得できます。
![VSCodeSnyk05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/e6f4e0e3-9765-ad8c-a7c1-c40d1c09659c.png)
「click to show」をクリックするとトークンが表示されるのでコピーします。
![VSCodeSynk06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/c4d99b33-4b67-023d-1c89-a35545442fa8.png)

VS Code で Snyk プラグイン画面を開き、拡張機能の設定を行います。
![VSCodeSynk07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/db0a589c-760c-b987-fb65-db79b5c5c614.png)
「snyk.advanced.tokenStorage」で「Snyk: Set Token」リンクをクリックし、表示される入力欄に先程のトークンを入力すると連携が完了します。
![VSCodeSynk08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/cf98ac9f-89e9-95f5-1535-22263619a409.png)

現時点でサポートしている IDE ついては [コチラ](https://docs.snyk.io/ide-tools) をご覧ください。

# コードリポジトリ と Snyk の連携
　開発に関わる全てのエンジニアが Snyk を利用するとは限りません。
エンジニアが脆弱性に気づかずに問題のあるコード、パッケージをコードリポジトリに格納した場合はあるでしょう。
本節ではそのようなときに備えてリポジトリ側を Snyk と連携させる例を紹介します。

　Snyk は GitHub を始め、GitLab、Bitbucket等の主要なソースコード管理サービスと連携させることができます。
今回は GitHub と連携させてみます。

　連携は Snyk の管理画面から行います。
プロジェクト画面の「Add project」ボタンをクリックすると連携先のサービスが表示されるので「GitHub」を選択します。
![AddProject01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/175c9ca0-0fab-1a9b-05c9-9ae7e3eecff5.png)
　すると自分の GitHub アカウントに存在するリポジトリ一覧が表示されるので、Snyk と連携したいリポジトリを選択します。今回は「snyk_demo」です。
![AddProject02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/739344a3-3b92-467a-2a27-a724150ad564.png)

　下記は先程のコードを脆弱性の解消をせずにこのリポジトリにプッシュした場合です。
VS Code の場合と同様にコードで中度(M)の警告が１つ、依存パッケージで中度の警告が４つ出ていることがわかります。
![GitDetectedBySnyk01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/bcce9806-ea37-359b-45fc-540ff1f527ac.png)
　「Code analysis」リンクをクリックして詳細を見てみましょう。
ここでもVSCode のときと同様にセキュアでないプロトコルを利用していることによる警告が出ていることが確認できます。
![GitDetectedBySnyk02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/19aec10b-c2f2-7c76-fb68-36b2a66ec8b2.png)

package.json の方も見てみます。
VS Code の場合と同様にクロスサイトスクリプティングを含めて4つの脆弱性が検知されています。
![GitDetectedBySnyk03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/b271bbaf-3c82-beef-ebc4-35a8a5aa99f2.png)

今回は検知だけでなく修正プルリクエストも自動で作られています。
その内容は「Fixes」タブで確認できます。
jquery を 2.2.4 から 3.5.0 にバージョンアップするプルリクエストが作られているので、問題なければ「Open a fix PR」をクリックします。
![GitDetectedBySnyk04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/575d5973-ba43-311c-3df4-eef87640ce5c.png)
今回のプルリクエストで解消される脆弱性の一覧が表示されるので、内容確認後「Open a Fix PR」をクリックし GitHub でプルリクエストを作成します。
![GitDetectedBySnyk05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/9fcddc6c-9695-6680-d095-a79e32739240.png)
GitHub を確認すると、Snyk によるプルリクエストが作成されたことが確認できます。
![GitDetectedBySnyk06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37758/21356da0-1a91-2727-8c6a-c78638616a78.png)

# まとめ
　以上、自分が書いたコードの脆弱性と、利用する OSS パッケージの脆弱性を Snyk を利用して発見・解消する方法について、IDEと連携させる場合とソースコード管理サービスと連携させる場合を紹介しました。

　開発フローをほとんど変えることなくアプリケーションのセキュリティを向上させることができるのは Snyk の大きな利点です。
まずは、自分の開発環境から Snyk を導入してみてはいかがでしょうか？

この記事がより安全なアプリケーション開発のお役に立てば嬉しいです。


# 参考情報
## 本記事の参考リンク
- [Snyk Code(コードスキャン)がサポートする言語](https://docs.snyk.io/products/snyk-code/snyk-code-language-and-framework-support)
- [Snyk Code のチェックルール](https://docs.snyk.io/products/snyk-code/security-rules-used-by-snyk-code)
- [Snyk Open Source がサポートするパッケージマネージャ](https://docs.snyk.io/products/snyk-open-source/language-and-package-manager-support)
- [Snyk がサポートする IDE](https://docs.snyk.io/ide-tools)
- [Snyk がサポートする Git リポジトリサービス](https://docs.snyk.io/integrations/git-repository-scm-integrations)
## 本記事で取り上げなかった機能について
### Snyk Container
アプリケーションをコンテナ化している場合、`Snyk Container` を利用することで実際に本番環境で利用されるイメージに脆弱性が含まれていないかをスキャンできます。
利用例は下記の記事がわかりやすいです。
- [Snyk Container の脆弱性スキャンでイメージ内のアプリケーション・ランタイム・ライブラリのバージョン情報を確認できるのか試してみた](https://dev.classmethod.jp/articles/check-the-runtime-version-in-the-images/)
### Snyk Infrastructure as Code
たとえ、コードに脆弱性がなかったとしてもインフラ部分に脆弱性があると情報漏えいにつながることがあります。
例えば、Amazon S3 の設定の不備により本来公開すべきでない情報が公開されてしまう場合などです。
Snyk Infrastructure as Code を利用するとインフラの構成管理ツールである Terraform 等の IaC のテンプレートに脆弱性につながる設定がないかチェックすることができます。
以下の記事では手元の環境と GitHub リポジトリの両方で Snyk Infrastructure as Code を利用した例が紹介されています。
- [Snyk IaC で HashiCorp Terraform のクラウド設定ミスを防ぐ](https://qiita.com/SnykSec/items/d9f3d44c83c233446b2b)