GitHub Code Scanning を使ってみた (YAMLの設定方法)

# はじめに
2020年9月30日に[GitHub Code Scanning](https://docs.github.com/ja/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/about-code-scanning)が一般公開された。([Blog記事](https://github.blog/2020-09-30-code-scanning-is-now-available/))

公式ドキュメントを読みつつ、実際に使ってみた内容を記事にまとめてみた。
いつものように[自ブログの英語ポスト](https://ymd_h.gitlab.io/ymd_blog/posts/github_code_scanning/)の日本語焼き直し版

# GitHub Code Scanningとは
GitHub Code Scanning は、GitHubが買収した[CodeQL](https://securitylab.github.com/tools/codeql)をベースに、コードの脆弱性を自動検出してくれるサービスです。

10月6日追記: [日本語の公式ブログ記事が公開されてました。](https://github.blog/jp/2020-10-06-code-scanning-is-now-available/)

# GitHub Code Scanning使い方
[GitHubの公式ドキュメント](https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/enabling-code-scanning-for-a-repository)は、いつものようにWeb UIでポチポチするチュートリアルしか記述していないが、GitHub Actionsの1つでしかないので、`.github/workflows`ディレクトリにYAMLファイルを配置することで利用することができるようになる。

Code Scanning のデフォルトのCodeQLを利用する設定の例は以下のような感じになる。

```yaml:.github/workflows/codeql-analysis.yml
name: CodeQL

on: [push, pull_request]

jobs:
  analyze:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 2
      - uses: github/codeql-action/init@v1
        with:
          languages: cpp, python
          queries: +security-and-quality
      - uses: github/codeql-action/autobuild@v1
      - uses: github/codeql-action/analyze@v1
```

`init`、`autobuild`、`analyze`の3つのステップからなっている。


## `init`

`init`では、スキャンする言語の指定や実行するクエリの種類などを指定する。
`language`パラメータとして指定できるのは、`cpp` (CとC++)、`csharp` (C#)、`java`、`javascript` (JavaScriptとTypeScript)、`python`、`go`である。
「, (カンマ)」で区切ることで複数の言語を指定できる。上の例では、１つのジョブで複数の言語を指定しているが、GitHubの公式ドキュメントでは、matrix戦略を利用して、言語ごとにジョブを分けることが推奨(?)されていた。

```yaml
# 前略
job:
  analyze:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        language: ['python', 'cpp']
    steps:
      - uses: actions/checkout@v2
      - uses: github/codeql-action/init@v1
        with:
          language: ${{ matrix.language }}
# 後略
```

`queries` でカスタムクエリを設定する事ができる。フルスクラッチも可能なようだが、2つのプリセットが用意されている。([参照](https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#running-additional-queries))

 * `security-extended`: デフォルトよりも重要度や精度が低いクエリ群
 * `security-and-quality`: `security-extended`に加えて、メンテナンス性や信頼性を主眼にしたクエリ群

例えば、Pythonで`security-and-quality`を指定すると、"unused import"や"import *"などが報告される。

先頭に`+`マークをつけることで、上書きではなく追加でクエリを設定できる。最初の例は、デフォルトのクエリに`security-and-quality`を追加している。

## `autobuild`

コンパイル言語をコンパイルするためのステップで、スクリプト言語しか利用しないのであればスキップすることが可能。`autobuild`が行うビルドプロセスは[こちら](https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-the-codeql-workflow-for-compiled-languages)に記載されている。
「一般的な」ビルド方法に則っていないケースは自動コンパイルに失敗することがもちろんあり、その際は手動でビルドする必要があるとのこと。


## `analyze`

CodeQLの主たるステップで、実際にコードスキャンを行い、結果を自動的にアップロードしてくれる。（特に設定したり言及したりするべきことはなさそう）

## 結果

結果は、Web上から確認できる。Securityタブの、「Code scanning alerts」にリストアップされる。偽陽性 (false positive)、テストコード、修正するつもりがない(won't fix)などの場合には手動で解決することができ、一度手動で解決した部分は次のスキャン時に再度報告されなくなる。（素晴らしい。）

# おわりに

GitHub Code Scanningを実際に設定しながら、使い方を整理してみた。
対応している言語であれば簡単に設定できてデメリットも特になさそうであったので、設定してみると良いと思う。
なお今回はGitHubが管理するCodeQLを利用する場合を調査したが、他にも対応するサードパーティ製のセキュリティースキャナー（例えば、少し前に話題になった[Trivy](https://github.com/aquasecurity/trivy-action)など）がマーケットプレイスにリストアップされていたので、CodeQLで満足しない方はいろいろ探してみると良いかもしれない。