メインコンテンツにスキップ
OpenAI

2026年3月16日

製品セキュリティ

Codex Security に SAST レポートが含まれない理由

何十年もの間、静的アプリケーションセキュリティテスト(SAST)は、セキュリティチームがコードレビューをスケールさせるうえで最も有効な手法のひとつとして使われてきました。

しかし Codex Security の設計にあたっては、あえて別の設計を採用しました。静的解析レポートを取り込んでエージェントにトリアージさせる、という出発点は採用しなかったのです。代わりに、リポジトリそのもの(アーキテクチャ、信頼境界、意図された挙動)から分析を始め、検出結果については、人間が確認に時間を割く前にシステム側で検証する設計にしました。

理由は明確です。最も厄介な脆弱性は、必ずしもデータフローの問題ではありません。コード上はセキュリティチェックが機能しているように見えても、そのチェックがシステムの前提となる性質を実際には保証していない場合があります。これが脆弱性につながります。つまり課題は、データがプログラム内をどのように流れるかを追跡することだけではありません。コードに組み込まれた防御が本当に機能しているかどうかを見極めることにあります。

問題点:SAST はデータフローに最適化されている

SAST はしばしば、明確なパイプラインとして捉えられます。信頼できない入力のソースを特定し、データの流れをプログラム全体で追跡し、そのデータがサニタイズされないまま機微なシンクに到達するケースを検出します。これは洗練されたモデルで、実際のバグの多くを捉えることができます。

しかし実際には、SAST は大規模なコードベースでも扱えるようにするため、近似に頼らざるを得ません。特に、間接参照、動的ディスパッチ、コールバック、リフレクション、そしてフレームワーク依存の制御フローを含む実際のコードベースではその傾向が顕著です。こうした近似は SAST の欠点というより、コードを実行せずに解析しようとする以上避けられない現実です。

ただ、これが Codex Security が SAST レポートを出発点としない理由というわけではありません。

より本質的な問題は、ソースからシンクまでの追跡に成功した後に何が起こるかにあります。

静的解析が苦手とする領域:制約とセマンティクス

静的解析が複数の関数やレイヤーをまたいで入力を正しく追跡できたとしても、脆弱性の有無を左右する次の問いに答える必要があります。

防御は本当に機能しているのか?

よくあるパターンとして、信頼できないコンテンツをレンダリングする前に sanitize_html() のような関数を呼び出すケースがあります。静的解析ツールは、サニタイザーが実行されたことまでは確認できます。しかし通常は、そのサニタイザーが、対象のレンダリングコンテキストやテンプレートエンジン、エンコーディングの挙動、さらに後続の変換を含めた状況において、本当に十分かどうかまでは判断できません。

ここが難しい点です。問題は、データがシンクに到達するかどうかだけではありません。コード内のチェックが、システムの前提どおりに値を適切に制約できているかどうかが重要です。

言い換えると、「コードがサニタイザーを呼び出していること」「システムが安全であること」は大きく異なります。

例:デコード前の検証

これは、実際のシステムで頻繁に見られるパターンです。

Web アプリケーションが JSON ペイロードを受け取り、redirect_url を抽出して許可リスト用の正規表現で検証し、その後 URL デコードして、結果をリダイレクトハンドラに渡すとします。

従来のソースからシンクへのレポートでは、フローを次のように説明できます:

信頼できない入力 → 正規表現チェック → URL デコード → リダイレクト

しかし、本当に重要なのは、そのチェックが存在するかどうかではありません。重要なのは、その後の変換を経ても、そのチェックが引き続き値を制約できているかどうかです。

正規表現チェックがデコード前に行われる場合、リダイレクトハンドラが解釈する形で、デコード後の URL を実際に制約できているのでしょうか?

これに答えるには、変換チェーン全体について推論する必要があります。つまり、正規表現が何を許容するのか、デコードと正規化がどう振る舞うのか、URL 解析がエッジケースをどう扱うのか、そしてリダイレクトロジックがスキームやオーソリティをどう解決するのかを見なければなりません。

実際に重要となる脆弱性の多くは、処理順序の誤り、部分的な正規化、解析の曖昧さ、検証と解釈の不一致などという形で現れます。データフロー自体は追跡可能です。問題は、制約が変換チェーンを通じてどのように引き継がれるか、あるいは引き継がれないかにあります。

これは単なる理論上の話ではありません。CVE-2024-29041(新しいウィンドウで開く) では、Express において、リダイレクト先のエンコードとその後の解釈の仕方に起因し、不正な形式の URL が一般的な許可リスト実装をバイパスできてしまうオープンリダイレクトの脆弱性が確認されました。データフロー自体は単純でした。より難しく、かつバグの有無を左右するのは、変換チェーンの後でもその検証が成立しているかどうかです。

私たちのアプローチ:挙動から出発し、そのうえで検証する

Codex Security は、より確かな根拠に基づいて問題を提示し、トリアージの負担を減らすというシンプルな目標に基づいて設計されています。製品では、リポジトリ固有の文脈(脅威モデルを含む)を踏まえたうえで、重要度の高い問題を隔離環境で検証し、その結果を提示します。 

Codex Security は、「検証」や「サニタイズ」と見える箇所に遭遇しても、それを単なるチェック項目としては扱いません。コードが何を保証しようとしているのかを見極め、その保証が成り立たないケースを検証します。

実際には、次のようなアプローチの組み合わせになることが一般的です。

  • セキュリティリサーチャーのように、リポジトリ全体のコンテキストを踏まえて関連するコードパスを読み、意図と実装の不一致を探すこと。これにはコメントも含まれますが、モデルはコメントをそのまま信じるわけではありません。そのため、実際にバグがある場合、コードの上に「これはバグではない」と書かれていても、それに惑わされることはありません。
  • 問題を最小限のテスト可能な単位(たとえば単一入力を中心とした変換パイプライン)に切り分け、システム全体に影響されずに検討できるようにすること。この意味で、Codex Security は小さなコード断片を抽出し、それぞれに対してマイクロファザーを作成します。
  • 各チェックを個別に扱うのではなく、変換全体を通じて制約がどのように保たれるかを検討すること。必要に応じて、これを充足可能性問題として定式化する場合もあります。言い換えると、モデルには z3-solver を備えた Python 環境へのアクセスが与えられており、特に複雑な入力制約の問題では、モデルは人間と同じように必要に応じてそれを使います。これは、非標準アーキテクチャ上での整数オーバーフローなどの解析に特に有効です。
  • 可能な場合は、サンドボックス化された検証環境で仮説を実行し、「問題になり得る」段階と「実際に問題である」段階を区別します。デバッグモードでコンパイルしたコードによるエンドツーエンドの PoC ほど確かな証拠はありません。 

これが重要な転換点です。「チェックが存在するかどうか」で止まるのではなく、「不変条件が成立しているかどうか」、そして「その根拠は何か」まで踏み込みます。そして、そのために最適なツールをモデル自身が選択します。

なぜ Codex Security は SAST レポートを初期入力として用いないのか

「両方やればよいのでは?」というのがもっともな疑問です。まず SAST レポートを出発点とし、その後エージェントでさらに深く検討すればよい、という考えです。

事前に計算された検出結果が有用な場合もあります。対象が限定された既知のバグ種別では特に有効です。しかし、文脈の中で脆弱性を発見し検証するよう設計されたエージェントにとっては、SAST レポートを出発点とすることで、予測可能な3つの問題が生じます。

第一に、探索の範囲を早い段階で狭めてしまう可能性があります。検出結果の一覧は、ツールがすでに調査した範囲を示す地図のようなものです。それを出発点にすると、システムは同じ領域に過剰にリソースを割き、同じ抽象化に依存し、ツールの前提に当てはまらない種類の問題を見落としやすくなります。

第二に、後から修正しにくい暗黙の前提が入り込む可能性があります。多くの SAST の検出結果には、サニタイズや検証、信頼境界に関する前提が組み込まれています。それらの前提が誤っている、または不十分な場合、それを推論プロセスに組み込むことで、エージェントの動きが「調査」ではなく「確認または却下」に偏ってしまう可能性があります。これは本来意図している使い方ではありません。

第三に、推論システムの評価が難しくなる可能性があります。パイプラインが SAST の出力から始まる場合、エージェント自身の分析によって得られた結果と、他のツールから引き継いだ結果とを区別するのが難しくなります。この区別は、システムの能力を正確に測定するうえで重要であり、その継続的な改善にも不可欠です。

そこで私たちは、セキュリティ研究と同じ出発点、すなわちコードとシステムの意図から始めるように Codex Security を設計しました。人間に対応を求める前に、検証によって十分な確信度まで高めることを重視しています。

SAST ツールは現在でも非常に重要です

SAST ツールは、本来の設計目的において非常に優れた性能を発揮します。安全なコーディング標準の適用、単純なソースからシンクへの問題の検出、そして既知のパターンを予測可能なトレードオフのもとで大規模に検出することに強みがあります。多層防御の重要な一部として機能します。

本稿では、より焦点を絞り、動作に基づいて検討し検出結果を検証するよう設計されたエージェントが、固定的な検出結果リストを出発点とすべきではない理由について述べます。

また、純粋なソースからシンクの考え方には限界がある点にも触れておきます。すべての脆弱性がデータフローの問題とは限りません。実際の不具合の多くは、状態や不変条件に関する問題です。たとえば、ワークフローの迂回、認可の抜け漏れ、あるいは「システムが誤った状態にある」ことによって生じるバグなどです。この種のバグでは、汚染された値が単一の「危険なシンク」に到達するとは限りません。リスクは、プログラムが常に成立すると前提している条件にあります。 

今後の取り組み

セキュリティツールのエコシステムは今後も進化し続けると考えられます。静的解析、ファジング、ランタイムガード、エージェント型ワークフローはいずれも重要な役割を担います。

Codex Security に期待しているのは、セキュリティチームにとって最もコストのかかる部分を担うことです。すなわち、「怪しい」という段階から、「実際の問題であること、その発生の仕方、そしてシステムの設計意図に沿った修正方法」まで明確にすることです。

Codex Security がリポジトリをどのようにスキャンし、検出結果を検証し、修正案を提示するのかについて詳しくは、ドキュメント(新しいウィンドウで開く)をご覧ください。

著者

OpenAI