GitHub の脆弱性検出機能 Code scanning alerts と CodeQL について

| 8 min read
Author: masahiro-kondo masahiro-kondoの画像

GitHub の public リポジトリでは、Settings の Security タブから Code scanning alerts を有効化できます。

Code scanning alerts は、コード分析エンジン CodeQL を使用してコードをスキャンし、検出したコードの脆弱性をアラートとして表示します。対応しているプログラミング言語は以下です。

  • C/C++
  • C#
  • Go
  • Java
  • JavaScript/TypeScript
  • Python
  • Ruby

About code scanning | GitHub Docs

機能の紹介としてはこれだけなのですが、CodeQL が気になったので少し調べてみました。

CodeQL は、GitHub により買収された Semmle 社によって開発されました。分析対象のコードの AST(抽象構文木)などを格納したデータベースを作成し、クエリを発行することで解析を行います。

以下のドキュメントに CodeQL についての説明があります。

About CodeQL — CodeQL

CodeQL の各データベースには、一つの言語の特定の時点におけるコードベースから抽出されたクエリ可能なデータが含まれています。データベースには、AST(抽象構文木)、データフローグラフ、制御フローグラフを含むコードの完全な階層的表現が含まれています。

各言語には、データベースの作成に使用される関係を定義する独自のデータベーススキーマがあります。スキーマは、抽出プロセス中の最初の字句解析と、CodeQL を使用した実際の複雑な解析との間のインターフェースを提供します。スキーマは、たとえば、すべての言語構成にテーブルがあることを指定します。

言語ごとに、CodeQL ライブラリは、データベーステーブルの抽象化レイヤーを提供するクラスを定義します。これにより、データのオブジェクト指向ビューが提供され、クエリの記述が容易になります。

たとえば、Java プログラムの CodeQL データベースでは、2つの主要なテーブルは次のとおりです。

  • expressions: ビルドプロセス中に分析されたソースコード内のすべての単一式の行を含む
  • statements: ビルドプロセス中に分析されたソースコード内のすべてのステートメントの行を含む

CodeQL ライブラリは、これらの各テーブル(および関連する補助テーブル)に抽象化レイヤーを提供するクラス Expr と Stmt を定義します。

ちょっとわかりづらいですが、言語ごとに専用のデータベーススキーマがあり、解析されたコードは (Java の場合) statements などの専用テーブルに格納され、CodeQL のライブラリには、クエリを発行するための専用クラス(Stmt など)があるということでしょう。

Semmle の LGTM というサイトで、クエリを試せます。

LGTM - Code Analysis Platform to Find and Prevent Vulnerabilities

Query console はこちら。

Query console | LGTM

JavaScript コードのコメントから TODO にマッチするものを抽出するクエリ。

import javascript

from Comment c
where c.getText().regexpMatch("(?si).*\\bTODO\\b.*")
select c

Java コードで、使用されていない関数の引数を抽出するクエリ。

import java

from Parameter p
where not exists(p.getAnAccess())
select p

SQL ライクな DSL でコードの該当箇所を抽出できることがわかります。各言語用 CodeQL 実装は以下のリポジトリで公開されています。

GitHub - github/codeql: CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security (code scanning), LGTM.com, and LGTM Enterprise

JavaScript の場合、CWE[1] タイプごとのクエリ実装は以下で見ることができます。

codeql/javascript/ql/src/Security at main · github/codeql

例えば、CWE-601: URL Redirection to Untrusted Site ('Open Redirect')CodeQL 実装は、以下のようになっていました。

import javascript
import semmle.javascript.security.dataflow.ServerSideUrlRedirectQuery
import DataFlow::PathGraph

from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Untrusted URL redirection due to $@.", source.getNode(),
  "user-provided value"

冒頭でも述べたように、Public なリポジトリでは、Code scanning alerts を有効化できます。Settings の Security タブ で Setup code scanning をクリックするとデフォルトでは CodeQL を使った GitHub Actions ワークフローの追加を行えます[2]

このボタンをクリックすると、リポジトリの .github/workflows 配下に codeql-analysis.yml を配置するためのワークフロー編集画面になります。
リポジトリで使用されている主要な言語から、strategy/matrix/language の配列に値が入ります。

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  workflow_dispatch:
    branches: [ "master" ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ "master" ]
  schedule:
    - cron: '40 16 * * 1'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'javascript' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        
        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        # queries: security-extended,security-and-quality

        
    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v2

    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

    #   If the Autobuild fails above, remove it and uncomment the following three lines. 
    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

    # - run: |
    #   echo "Run, Build Application using script"
    #   ./location_of_script_within_repo/buildscript.sh

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2

workflow_dispatch(手動)、pull_request の他に、schedule として crontab 形式で起動するようなテンプレートになっています。これは、コード変更しなくても、新種の脆弱性発見の可能性があるため、定期的に点検する必要があるからでしょう。

使用されているのは、GitHub 公式 codeql-action です。

GitHub - github/codeql-action: Actions for running CodeQL analysis

2023.01.10追記

Python / JavaScript / Ruby のリポジトリではワークフローファイルを追加しなくても簡単に Code scanning を有効化できるようになりました。

Default setup: A new way to enable GitHub code scanning | The GitHub Blog

このワークフローファイルをリポジトリに登録して実行すると結果が GitHub にアップロードされます。

スキャン結果は、Seccurity の Code scanning alerts の View alerts から見ることができます。

このスキャンに関しては問題は検出されなかったようです。

今月初め Code scanning alerts が PR に対してコメント挿入する機能がリリースされました。

Users can view and comment on code scanning alerts on the Conversation tab in a pull request | GitHub Changelog

ドキュメントから PR コメントのスクリーンショットを掲載します。

Bot がインラインで指摘してくれるため、マージ前に対応することができます。

CodeQL のリポジトリでは、すでに Swift のサポートが実装中のようですし、Kotlin のサポートも計画されているようです。

このように素晴らしい Code scanning ですが、private リポジトリについては有償で、Security の Code scanning alerts のセクションは Contact sales になっています。

また、GitHub Actions で CodeQL CLI[3] を使用するのも、private リポジトリについては、GitHub Advanced Security ライセンスが必要です。

About CodeQL code scanning in your CI system | GitHub Docs

Note: The CodeQL CLI is free to use on public repositories. The CodeQL CLI is also available in private repositories owned by organizations that use GitHub Enterprise Cloud and have a license for GitHub Advanced Security.

VS Code の拡張機能を使ってローカル環境で CodeQL のスキャンを実施することも可能ですが、やはり CI で実施したいところですね。

GitHub の Alert で見えるのは脆弱性だけですが、LGTM にサインアップして、public リポジトリを登録すれば、セキュリティ以外の静的コード分析結果レポートを見ることもできます。


  1. Common Weakness Enumeration(共通脆弱性タイプ一覧): ソフトウェアの脆弱性を分類するための共通基準。 ↩︎

  2. Configure other scanning tools を選択すると Marketplace からサードパーティの Action を選択して設定可能です。 ↩︎

  3. CodeQL のスキャンを直接実装する CLI。CodeQL CLI — CodeQL ↩︎

豆蔵では共に高め合う仲間を募集しています!

recruit

具体的な採用情報はこちらからご覧いただけます。