GitHub で CodeQL を探索する
CodeQL とは
CodeQL は、コードをデータとして扱う GitHub によって開発されたセマンティック コード分析エンジンです。 単純にテキスト パターンを検索するのではなく、CodeQL はコードの構造と意味を理解し、高度なセキュリティと品質分析を可能にします。
従来の静的分析ツールでは、単純なパターン マッチングを使用するため、誤検知が発生することがよくあります。 CodeQL のセマンティック アプローチでは、コード コンテキスト、コード要素間のリレーションシップ、アプリケーション間のデータ フローが理解されるため、より正確な脆弱性検出が行われます。
CodeQL の主な特性
CodeQL は、コードをデータベースとして扱います。
- 構造表現: ソース コードを、構文ツリー、制御フロー グラフ、およびデータ フロー パスをキャプチャするデータベースに変換します。
- クエリ可能な形式: 従来のデータベースのクエリと同様に、特殊なクエリ言語を使用してコードをクエリ可能にします。
- 言語に依存しないアプローチ: C/C++、C#、Java、JavaScript/TypeScript、Python、Ruby、Go、Swift などの複数のプログラミング言語をサポートします。
- 包括的なカバレッジ: 個々のファイルだけでなく、すべての相互接続を使用してコードベース全体を分析します。
CodeQL を使用すると、正確なセキュリティ分析が可能になります。
- バリアント分析: 1 つの脆弱性を特定したら、クエリを記述して、コードベース全体で同様の問題を見つけることができます。
- データ フロー分析: ソース (ユーザー入力) からシンク (機密性の高い操作) へのアプリケーション間のデータの移動方法を追跡します。
- テイント追跡: 信頼されていないデータが、適切な検証やサニタイズなしで機密性の高い操作に到達するタイミングを識別します。
- 制御フロー分析: 特定の条件下でのみ発生する脆弱性を見つけるための実行パスと条件付きロジックについて説明します。
CodeQL のしくみ
CodeQL 分析には、ソース コードを実用的なセキュリティ結果に変換する 3 つの異なるフェーズが含まれます。
フェーズ 1: CodeQL データベースを作成する
最初の手順では、コードの構造化表現を抽出します。
- コードの抽出: コンパイル中または静的分析を使用して、ソース ファイルを分析します。
- データベースの作成: 抽象構文ツリー、制御フロー グラフ、データ依存関係など、コードの構造を表す包括的なデータベースを構築します。
- メタデータ キャプチャ: ファイルの場所、行番号、変数スコープ、関数呼び出し、およびクラス階層を記録します。
- 最適化: 大規模なコードベースでも、効率的なクエリを実行するためにデータベースのインデックスを作成します。
このデータベースは、後続のすべての分析の基礎になります。 これは 1 回作成され、複数回クエリを実行できるため、反復的なセキュリティ分析が効率的になります。
フェーズ 2: CodeQL クエリを実行する
データベースが存在したら、クエリを実行してセキュリティの問題を見つけます。
- 標準クエリ パック: GitHub には、一般的な脆弱性 (OWASP Top 10、CWE 標準) のキュレーションされたクエリ セットが用意されています。
- カスタム クエリ: 組織固有のセキュリティ パターンまたはコーディング標準違反を見つけるための独自のクエリを記述します。
- クエリの実行: CodeQL エンジンは、データベースに対してクエリを実行し、脆弱性シグネチャと一致するコード パターンを検索します。
- パフォーマンス: クエリは、生のソース ファイルではなくインデックス付きデータベースで動作するため、迅速に実行されます。
クエリ カテゴリの例を次に示します。
- インジェクションの脆弱性: SQL インジェクション、コマンド インジェクション、クロスサイト スクリプティング。
- 認証の問題: 脆弱なパスワード ポリシー、認証チェックの不足、セキュリティで保護されていないセッション管理。
- 暗号化の問題: 脆弱なアルゴリズム、ハードコーディングされた資格情報、不十分なランダム性。
- リソース管理: メモリ リーク、リソースの枯渇、制御されていないリソースの消費。
フェーズ 3: 結果を解釈する
最後のフェーズでは、アクション可能な形式で結果を示します。
- 結果のランク付け: CodeQL は、重大度、信頼度、悪用可能性によって結果に優先順位を付けます。
- コンテキスト情報: 各検索には、ファイルの場所、行番号、影響を受けるコード スニペット、およびデータ フロー パスが含まれます。
- 修復ガイダンス: 結果には、脆弱性の説明と修正に関する推奨事項が含まれます。
- 統合: 結果は、GitHub の [セキュリティ] タブ、pull request 注釈、および外部ツール用の SARIF ファイルと統合されます。
CodeQL クエリ言語
CodeQL クエリは、コードを分析するために特別に設計された宣言型言語で記述されます。
クエリの構造と構文
CodeQL では、オブジェクト指向のロジック プログラミングを使用します。
- クラスと述語: コード要素 (関数、変数、式) を表すクラスを使用して検索対象を定義します。
- 宣言型アプローチ: 検索方法ではなく、検索する内容を説明します。
- パターン マッチング: 述語を使用して、コード パターンとリレーションシップを照合します。
- コンポーザビリティ: より単純な述語を組み合わせて複雑なクエリを作成します。
クエリ構造の例:
import javascript
from SqlExecution sql, Source source
where source.flowsTo(sql.getAnArgument())
select sql, "SQL query vulnerable to injection from $@.", source, "user input"
このクエリでは、次の方法で SQL インジェクションの脆弱性を検出します。
- SQL 実行ポイントの識別。
- ユーザー入力のソースの検索。
- 入力から SQL 実行へのデータ フローの追跡。
- コンテキストを使用して脆弱性を報告する。
標準クエリ ライブラリ
GitHub には、広範なクエリ ライブラリが用意されています。
- セキュリティ クエリ: OWASP の上位 10 件の脆弱性、CWE カテゴリ、言語固有のセキュリティの問題を検出します。
- コード品質クエリ: コードの臭い、保守容易性の問題、パフォーマンスの問題、ベスト プラクティス違反を見つけます。
- コミュニティの投稿: セキュリティ研究者や開発者が提供する何千ものクエリ。
- 定期的な更新プログラム: GitHub Security Lab は、新たな脆弱性に対する新しいクエリを継続的に追加します。
これらのクエリは as-is 使用することも、特定のニーズに合わせてカスタマイズすることもできます。
GitHub セキュリティにおける CodeQL
CodeQL は、GitHub のセキュリティ機能と深く統合されています。
CodeQL を使用したコード スキャン
自動セキュリティ分析:
- 既定のセットアップ: リポジトリ設定でワンクリックで CodeQL スキャンを有効にします。
- スケジュールされたスキャン: プッシュ、プル要求、またはスケジュールごとに自動的にスキャンします。
- 複数言語のサポート: リポジトリ内の言語を自動的に検出し、適切なクエリを実行します。
- 結果の表示: セキュリティの結果は、[セキュリティ] タブに詳細な説明と共に表示されます。
Pull request の統合:
- インライン注釈: セキュリティの結果は、pull request の脆弱なコード行に直接コメントとして表示されます。
- ブロッキング チェック: マージする前に合格する必要がある必須チェックとして CodeQL を構成します。
- 差分スキャン: pull request によって導入された新しい脆弱性のみを報告し、ノイズを減らします。
- 開発者からのフィードバック: 開発者は、コードが最新の状態である間、セキュリティの問題をすぐに確認できます。
GitHub Advanced Security
組織向けに、GitHub Advanced Security には追加の機能が用意されています。
- プライベート リポジトリのスキャン: プライベート リポジトリで CodeQL を実行します。
- カスタム クエリの実行: 組織固有のクエリをアップロードして実行します。
- セキュリティの概要: すべてのリポジトリのセキュリティ体制を示すダッシュボード。
- アラート管理: チーム間でセキュリティの結果をトリアージ、割り当て、追跡します。
CI/CD パイプラインでの CodeQL の使用
CodeQL は GitHub を超えて拡張され、さまざまな CI/CD システムと統合されます。
統合アプローチ
GitHub Actions の統合:
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: javascript, python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
このワークフロー:
- 指定した言語の CodeQL を初期化します。
- アプリケーションをビルドします (またはビルドせずに分析します)。
- セキュリティ クエリを実行します。
- 結果を GitHub の [セキュリティ] タブにアップロードします。
Azure Pipelines の統合:
CodeQL は、コマンド ライン インターフェイスを使用して Azure Pipelines で実行できます。
- CodeQL CLI をインストールします。 CodeQL バンドルをダウンロードしてパイプラインにインストールします。
-
データベースの作成: ビルド中に
codeql database createを実行します。 -
データベースの分析: 選択したクエリ パックで
codeql database analyzeを実行します。 - 結果のエクスポート: Azure DevOps で視覚化するための SARIF ファイルを生成します。
その他の CI/CD システム:
CodeQL CLI では、任意の CI/CD プラットフォームがサポートされます。
- ジェンキンス: ビルド ステップとして CodeQL 分析を実行します。
- GitLab CI/CD: SARIF 出力を使用して GitLab パイプラインで CodeQL を実行します。
- CircleCI: CodeQL スキャンを CircleCI ワークフローに統合します。
- カスタム システム: コマンドライン ツールを実行できる任意の環境から CodeQL CLI を使用します。
セキュリティ ゲート
品質ゲートとして CodeQL の結果を使用します。
- ビルドの失敗: CodeQL が重大度の高い脆弱性を検出したときに失敗するようにパイプラインを構成します。
- 傾向分析: 時間の経過に伴うセキュリティ メトリックを追跡して、改善を測定します。
- コンプライアンス要件: 監査とコンプライアンス認定のセキュリティ スキャンの証拠を生成します。
- 自動修復: 特定の脆弱性が検出されたときに自動化されたワークフローをトリガーします。
CodeQL 開発ツール
CodeQL には、クエリを作成およびテストするためのツールが用意されています。
Visual Studio Code 拡張機能
VS Code 用の公式 CodeQL 拡張機能は、次の内容を提供します。
- クエリ開発: 構文の強調表示、オートコンプリート、インライン ドキュメントを使用して、CodeQL クエリを記述してテストします。
- ローカル データベース分析: ローカル コードベースから作成されたデータベースに対してクエリを実行します。
- 結果の視覚化: ソース コード ナビゲーションとデータ フロー パスを使用してクエリ結果を表示します。
- デバッグのサポート: クエリの実行をステップ実行して結果を理解し、パフォーマンスを最適化します。
コマンドラインインターフェース
CodeQL CLI を使用すると、スクリプト可能な分析が可能になります。
-
データベースの作成:
codeql database createは、クエリ可能な形式でコードを抽出します。 -
クエリの実行:
codeql database analyzeはクエリを実行し、結果を生成します。 -
テスト クエリ:
codeql test runは、テスト ケースに対するクエリを検証します。 - パック管理: 標準クエリ パックをダウンロードして管理します。
セキュリティ自動化のための CodeQL の利点
CodeQL を DevSecOps プロセスに統合すると、大きな利点があります。
開発者の生産性
早期検出:
- シフトレフトセキュリティ: 運用環境ではなく、開発中に脆弱性を発見する。
- 迅速な修復: コードが新しく、変更が小さい場合の問題を修正します。
- 学習機会: 開発者は、すぐにフィードバックを得て、セキュリティで保護されたコーディングプラクティスを学習します。
- コンテキスト切り替えの削減: セキュリティの結果は、使い慣れた開発ツールに表示されます。
正確な結果:
- 低い偽陽性: セマンティック分析では、パターン マッチングよりも正確な結果が得られます。
- コンテキスト情報: 結果には、脆弱性がどのように発生するかを正確に示すデータ フロー パスが含まれます。
- 優先順位付けされた結果: 理論的な懸念ではなく、悪用可能な問題に焦点を当てます。
- バリアント検出: 明らかな例だけでなく、脆弱性パターンのすべてのインスタンスを見つけます。
組織のセキュリティ
包括的な範囲:
- コードベース全体: サードパーティの依存関係やレガシ コンポーネントを含むすべてのコードを分析します。
- 複数の言語: ポリグロット アプリケーション全体の統一されたセキュリティ分析。
- 一貫性のある標準: すべてのリポジトリに同じセキュリティ規則を適用します。
- 履歴分析: 既存のコードをスキャンしてセキュリティ ベースラインを確立します。
スケーラブルなセキュリティ:
- 自動スキャン: すべてのコミットに対して手動のセキュリティ レビューは必要ありません。
- 継続的な監視: 定期的なスキャンでは、新しく開示された脆弱性が検出されます。
- コードとしてのセキュリティ: バージョン管理に格納されているクエリとしてセキュリティ要件を体系化します。
- ナレッジ共有: クエリ ライブラリは、制度上のセキュリティの知識をキャプチャします。
コンプライアンスとガバナンス
監査証跡:
- スキャン履歴: タイムスタンプと結果を含むすべてのセキュリティ スキャンの記録。
- ライフサイクルの検索: 検出から修復までの脆弱性を追跡します。
- ポリシーの適用: リリースごとにセキュリティ スキャンが行われることを示します。
- 証拠の生成: 監査者とコンプライアンス フレームワークのレポートを作成します。
CodeQL の詳細については、「 CodeQL の概要」を参照してください。
使用可能なツールについては、「 CodeQL ツール」を参照してください。