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: $
# 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

このワークフローファイルをリポジトリに登録して実行すると結果が 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 ↩︎

豆蔵デベロッパーサイト - 先週のアクセスランキング
  1. Nuxt3入門(第1回) - Nuxtがサポートするレンダリングモードを理解する (2022-09-25)
  2. 自然言語処理初心者が「GPT2-japanese」で遊んでみた (2022-07-08)
  3. GitHub Codespaces を使いはじめる (2022-05-18)
  4. Jest再入門 - 関数・モジュールモック編 (2022-07-03)
  5. ORマッパーのTypeORMをTypeScriptで使う (2022-07-27)
  6. Nuxt3入門(第4回) - Nuxtのルーティングを理解する (2022-10-09)
  7. Nuxt3入門(第3回) - ユニバーサルフェッチでデータを取得する (2022-10-06)
  8. 第1回 OpenAPI Generator を使ったコード生成 (2022-06-04)
  9. Nuxt3入門(第8回) - Nuxt3のuseStateでコンポーネント間で状態を共有する (2022-10-28)
  10. Nuxt3入門(第2回) - 簡単なNuxtアプリケーションを作成する (2022-10-02)