Snykのコードスキャンをneovimで動かしてみました

2022.10.25

こんにちは、AWS事業本部コンサルティング部に所属している今泉(@bun76235104)です。

以前Snyk CodeとVSCodeの拡張機能を利用して開発中コードのセキュリティスキャンを行ってみました。

私は平時neovimを利用していて、作業の性質上好ましい場合はVSCodeを利用するようにしています。

この記事を書いたときはIDE plugins | Snykのページをみて、「vimやneovimはないんだなぁ」と軽く流していました。

snyk_integration_no_vim

先日別の記事を書いている時に「LSPのしくみに乗せれば、違うエディタでも同じような機能が使える昨今、何か用意されているはずでは?」と思いなおし、調べたところすぐに公式のドキュメントを発見しました。

neovimの設定の例まで掲載されているので、これはやるしかない!

ということでドキュメントに従ってneovimでSnyk Codeの指摘を表示させてみました!

なお、LSPの概念については以下記事が非常にわかりやすかったので、良くわからない方はぜひご参照ください。

私の環境

OSなどによって、手順や設定方法が異なりますが、私は以下環境で試しています。

項目
OS macOS Monterey
nvim version 0.8.0
Go version 1.19

SnykのLSPサーバーをインストールする方法

Where you can download the Language Serverのセクションにあるコマンドを実行しても良いと思いますが、私はソースコードからビルドすることにしました。

Github上のsnyk/snyk-lsのinstallationのセクションを参照します。

前提条件として、go1.18以上の実行ができること、GOPATHやGOROOTを設定していることが必要となります。

以下コマンドを実行しました。

git clone https://github.com/snyk/snyk-ls.git
cd snyk-ls
go get ./...
make build && make install

これで snyk-ls コマンドが実行できればインストール完了です。

正常にmakeコマンドが終了したのにnot foundになる場合は、インストールされたディレクトリへのパスが通っていない可能性があります。

以下記事などを参考にしてGOBINへのパスが通っているか確認してみてください。

snyk-lsの認証について

Language ServerのAuthentication for Snyk Language Serverのセクションに記載があるように、snyk-lsは以下順位で認証を試行するようです。

  1. synk-lsのinitializationOptionに渡されるtokenの値
  2. SnykCLIを介して認証
    • Auth - Snyk User Docsを参照
    • ※ 後述しますが、私の環境の場合snyk-cliによる認証済みでも毎回ブラウザが開かれました
  3. ブラウザを開いて認証しようとする

事前にSnykCLIでsnyk authにより認証を済ませました。

neovimでSnykのLSPサーバーを使用できるように設定

Example Configuration for Neovimにneovim用の設定例が掲載されています。

基本的にこの設定をコピペすれば良いと思うのですが、私は以下のように一部設定を変更しました。

-- for snyk setting
local lspconfig = require('lspconfig')
local configs = require 'lspconfig.configs'
local snyk_ls_path = '/Users/imaizumi.taiki/go/bin/snyk-ls'

if not configs.snyk then
    configs.snyk = {
        default_config = {
            cmd = {snyk_ls_path},
            root_dir = function(name)
                return lspconfig.util.find_git_ancestor(name) or vim.loop.os_homedir()
            end,
            init_options = {
                activateSnykCode = "true",
                -- organizationに加入している場合はこの設定が必要
                organization = "組織名",
            }
        };
    }
    lspconfig.snyk.setup {
      on_attach = on_attach
    }
    print [[You can find your log at $HOME/.cache/nvim/lsp.log. Please paste in a github issue under a details tag as described in the issue template.]]
end

私の環境の場合、すでにwbthomason/packer.nvimでパッケージの管理しているため、一部のコードのみ追記しています。

ここまで終えたのでnodejs-goofよりサンプルプロジェクトをcloneしてきます。

サンプルプロジェクトのapp.jsをneovimで開くと、以下のようにメッセージが表示されて、ブラウザでSnykの認証画面が開きました。

You can find your log at $HOME/.cache/nvim/lsp.log. Please paste in a github issue under a details tag as described in the issue template.
LSP[snyk][Info] Authenticating to Snyk. This could open a browser window.

snyk_cli_request_auth_20221024

Authenticateを押下することで、以下画面に遷移して、認証が完了しました。

snyl_cli_autehnticated_20221024

neovim上で数秒待っていると、以下のようにSnykCodeでスキャンをしてくれました!

nvim_snyk_code_running_20221024

ただし、私の環境ではsnyk-cliの認証はsnyk authで実行しているのですが、nvimでファイルを開くたびにブラウザでSnykの認証画面が開いてしまいました。

SnykのTokenをneovimで設定

[GitHub Actions] Snyk Node Actionを使ってCI Workflow上で脆弱性のチェックをしてみたの記事を参考にして、SnykのダッシュボードからTokenを発行します。

以下のようにneovimの設定ファイルでtokenを渡すことで、ブラウザ認証が発生せず、コードスキャンができることを確認しました。

-- for snyk setting
local lspconfig = require('lspconfig')
local configs = require 'lspconfig.configs'
local snyk_ls_path = '/Users/imaizumi.taiki/go/bin/snyk-ls'

if not configs.snyk then
    configs.snyk = {
        default_config = {
            cmd = {snyk_ls_path},
            root_dir = function(name)
                return lspconfig.util.find_git_ancestor(name) or vim.loop.os_homedir()
            end,
            init_options = {
                activateSnykCode = "true",
                organization = "組織名",
                -- tokenを設定する場合(TOKENの取り扱いには要注意!)
                token = "TOKENを設定"
            }
        };
    }
    lspconfig.snyk.setup {
      on_attach = on_attach
    }
    print [[You can find your log at $HOME/.cache/nvim/lsp.log. Please paste in a github issue under a details tag as described in the issue template.]]
end

これですと、vimの設定ファイルにtokenを直書きとなってしまうため、以下のように環境変数を読み込ませるようにしても良いかもしれません。

token = vim.env.SNYK_TOKEN

Snykを特定のディレクトリ配下でしか実行しない場合、以下のようにdirenvなどのしくみと連携して環境変数の有無でSnykCodeを利用するか分岐しても良いかもしれません。

if not configs.snyk and vim.env.SNYK_TOKEN then

まとめ

  • SnykはLSPサーバーを提供してくれている
  • LSPが使える環境ならいろいろなエディタで動作させることができそう
  • Tokenの流出には注意

Snykとても面白いですね。

今後もいろいろ触って行きたいと思います!