GitHub の脆弱性検出機能 Code scanning alerts と CodeQL について
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 についての説明があります。
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 はこちら。
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 実装は以下のリポジトリで公開されています。
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
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 に対してコメント挿入する機能がリリースされました。
ドキュメントから 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 リポジトリを登録すれば、セキュリティ以外の静的コード分析結果レポートを見ることもできます。
Common Weakness Enumeration(共通脆弱性タイプ一覧): ソフトウェアの脆弱性を分類するための共通基準。 ↩︎
Configure other scanning tools
を選択すると Marketplace からサードパーティの Action を選択して設定可能です。 ↩︎CodeQL のスキャンを直接実装する CLI。CodeQL CLI — CodeQL ↩︎