機能を無効化したとき、実際には何が停止するのだろうか。例えば、サーバーが受け付ける署名アルゴリズムを許可リストで管理し、特定の方式をリストから除外したとする。管理者が期待するのは、その方式による認証要求が拒否されることである。しかし、認証の可否を判断するまでに、サーバーはクライアントから受信したデータを処理しなければならない。署名アルゴリズムの識別だけで拒否できる実装もあれば、公開鍵の内部構造を解析した後に許可リストを確認する実装もある。どちらも最終的には認証を拒否するが、拒否に至るまでに実行されるコードの範囲は異なる。
この違いは、認証結果だけを観測しても特定できない。禁止された署名アルゴリズムで認証を試み、サーバーから「認証失敗」が返された場合、その要求について認証が成立しなかったことは確認できる。一方、拒否されるまでにどの解析器が呼び出され、どのデータが解釈され、どの検証処理が実行されたかは、応答だけでは分からない。例えば、許可リストとの照合前に公開鍵の内部構造を解析する実装では、最終的に使用を禁止されているアルゴリズムの解析処理にも、外部から与えられた入力が到達する可能性がある。
認証前に実行される処理は、認証の成否とは独立した攻撃対象になり得る。公開鍵の解析器に未知の欠陥が存在し、その欠陥を特定の入力によって発現させられる場合、認証を成功させる必要はない。攻撃者は認証前の接続を確立し、解析器へ問題のあるデータを渡せればよい。解析器が入力を処理した後で認証を拒否しても、すでに実行された処理への影響は取り消されない。ただし、コードへ到達できることと、そのコードに悪用可能な欠陥が存在することは異なる。到達可能性は攻撃が成立するための条件の一つであり、攻撃の成立には欠陥の存在や入力条件なども関係する。
ここには、機能の利用可否と、その機能に関連する処理の実行可否という二つの制御がある。前者は認証を成功させるかどうかを決め、後者は認証結果が確定するまでにどの処理を実行するかを決める。管理者が署名アルゴリズムを無効化しても、実装がその設定を認証の最終判定にしか使用していなければ、解析処理の到達可能性は維持される。逆に、許可判定に必要な情報を識別した段階で禁止対象を拒否する実装では、その後に続く不要な解析処理を実行せずに済む。両者の差は設定値の記述方法ではなく、設定を参照する位置と制御フローの関係から生じる。
既稿「AI エージェントの安全境界は改変・探索・再利用できる経路から分離する」では、規則を保持することと、規則に反する操作を実行系が遮断できることの差を扱った[1]。一般のソフトウェアでも、設定が表す制限と実行時に成立する制限には同じ区別がある。また、Saltzer と Schroeder が整理した完全仲介の原則は、保護対象へのアクセスを適切な保護機構によって検査することを求めている[2]。この原則は、許可判定を迂回するアクセス経路を残さないための基礎となる。ただし、機能の無効化はアクセス制御より広い概念であり、許可判定に必要な識別処理まで停止させることが常に適切とは限らない。許可を判断するために必要な処理と、許可された場合にだけ必要になる処理を区別する必要がある。
機能を無効化した設定があっても、その機能に関連する処理が到達不能になるとは限らない。実際の制限は、許可判定の位置、判定に用いる情報、そこへ至る実行経路によって決まる。設定された禁止条件に対して、どの処理が実行され、どの処理が遮断されるかを確認することで、機能の無効化がどの範囲まで成立しているかを評価できる。認証が失敗したという結果は利用の拒否を示すが、関連する解析処理が実行されなかったことを示すには、実行経路についての追加の根拠が必要になる。
1. 無効化された機能はどこまで停止するのか
署名アルゴリズムの許可リストは、サーバーがどの方式による認証を受け付けるかを定める。管理者がある方式をリストから除外すると、その方式による認証を成功させないことが期待される。しかし、受信したデータがどの方式に属するかを判断する処理と、その方式を使用して認証を行う処理は、実装上は別々の段階に分かれている。サーバーは入力を受信した時点で、そのデータが許可された方式に属することを必ずしも把握していない。方式を識別するための情報を読み取り、許可リストと照合し、許可された場合に必要な解析や検証を実施するという順序が考えられる。
これに対して、汎用的な公開鍵解析器へ受信データを渡し、鍵オブジェクトを生成してから許可リストを確認する実装を考える。解析器が鍵の種類に応じて異なる処理へ分岐するなら、許可されていない方式に固有の解析処理も、許可判定前に実行される可能性がある。解析器が入力の長さ、内部構造、符号化形式などを調べる過程で、外部から与えられた値がメモリ操作や条件分岐に影響する。最終的な認証結果が拒否であっても、その前に実行された解析処理は認証失敗によって無効化されるわけではない。
許可判定をどこに配置するかによって、同じ要求に対する実行経路は変わる。例えば、受信データから署名方式の識別情報を取得した直後に許可リストと照合する実装では、禁止対象を早期に拒否できる。一方、鍵の内部構造を解析した後に照合する実装では、解析器までの経路が残る。さらに、解析後に署名検証も実行する設計であれば、検証処理まで到達する場合がある。実際にどの段階まで進むかは、入力形式、処理間の依存関係、許可判定の実装によって異なる。
| 比較項目 | 識別後に許可判定する実装 | 詳細な解析後に許可判定する実装 |
|---|---|---|
| 受信データの取得 | クライアントからデータを受信する。 | クライアントからデータを受信する。 |
| 方式の識別 | 許可判定に必要な情報を取得する。 | 許可判定に必要な情報を取得する。 |
| 許可リストとの照合 | 禁止された方式を詳細な解析前に拒否する。 | 詳細な解析を実行した後に禁止された方式を拒否する。 |
| 禁止対象に固有の解析処理 | 早期に拒否された要求では実行されない。 | 許可判定前に実行される可能性がある。 |
| 最終的な認証結果 | 禁止された方式による認証を拒否する。 | 禁止された方式による認証を拒否する。 |
| 攻撃対象となる処理 | 受信処理と許可判定に必要な識別処理が残る。 | 受信処理と識別処理に加え、禁止対象の詳細な解析処理も含まれ得る。 |
表の二つの実装は、禁止された署名アルゴリズムによる認証を拒否するという機能上の要求を満たしている。しかし、未認証のクライアントが実行させられる処理の範囲には差がある。識別後に許可判定する実装では、禁止対象に固有の詳細な解析処理へ進む前に要求を終了できる。詳細な解析後に判定する実装では、許可されていない方式の解析器まで到達する経路が残る。認証結果を比較する試験だけでは、この実行経路の差を検出できない。
ただし、許可判定を無条件に処理の先頭へ移せばよいわけではない。受信データが申告する方式と、実際に格納されている鍵の種類が異なる場合、申告された識別情報だけを確認しても、後続の解析器が処理する対象を正しく制限できない。許可された方式を申告したデータの内部に、別の方式の鍵が格納されている可能性があるためである。許可判定に用いた識別情報と、実際に解析・検証する対象が一致していることも確認する必要がある。入力の正規化や形式の識別が必要な場合には、それらをどの段階で実行し、どの範囲まで未信頼入力を処理するかが設計上の条件となる。
外部からの入力が解析器へ到達できることは、その解析器が攻撃対象となり得ることを意味する。ただし、解析器の存在だけで脆弱性が成立するわけではない。攻撃が成立するには、到達可能なコードに悪用可能な欠陥があり、その欠陥を発現させる入力を攻撃者が与えられる必要がある。禁止された方式の解析処理を到達不能にすれば、その経路を通じた悪用の機会を減らせる。一方、許可された方式に必要な解析処理や、方式を識別するために必要な処理は引き続き実行されるため、それらの安全性は別途確認しなければならない。
機能の無効化を検証する際には、少なくとも二つの観測が必要になる。一つは、禁止された方式による要求が認証に成功しないことである。もう一つは、その要求が拒否されるまでに、禁止対象に固有の処理が実行されたかどうかである。前者は認証結果を確認する試験で評価できる。後者は、実行経路の解析、処理の呼び出し状況の観測、拒否経路を通る入力を用いた検証などによって確認する。両者を区別することで、設定された禁止条件が認証結果だけに作用しているのか、それとも不要な処理への到達経路も制限しているのかを判断できる。
2. 実行可能な処理をグラフで表す
ソフトウェアの実行経路は、関数や処理段階を頂点、処理間の遷移を辺とする有向グラフとして表せる。例えば、サーバーが認証要求を受信し、公開鍵の種類を識別し、鍵の内部構造を解析し、署名を検証して認証結果を返す場合、それぞれの処理を頂点として配置できる。処理の実行順序や分岐条件は頂点間の辺として表現される。OWASP の攻撃対象領域分析でも、外部からアクセスできる入口と、そこから到達する機能やデータを特定することが基本となる[3]。この考え方を実行経路へ適用すると、設定によって利用を禁止した機能のうち、どの処理が外部入力から実行可能な状態に残っているかを調べられる。
ただし、ソースコード上で関数の呼び出し関係が存在することと、その関数が特定の条件で実行可能であることは異なる。例えば、認証に成功した場合だけ進める処理は、未認証のクライアントから直接実行できる経路には含まれない。また、署名アルゴリズムの許可リストによって分岐が制限される場合、同じプログラムでも設定によって実行可能な経路が変わる。この違いを表すため、グラフを設定と実行状態に依存するものとして定義する。
設定を \(c\)、認証前・認証後などの実行状態を \(q\) とする。処理の頂点集合を \(V\)、その条件下で実行可能な遷移集合を \(E_{c,q}\) と置けば、実行グラフは次のようになる。
\[ G_{c,q}=(V,E_{c,q}). \]
\(V\) はプログラムに存在する処理の集合であり、\(E_{c,q}\) は設定 \(c\) と状態 \(q\) の下で実行できる遷移の集合である。例えば、サーバーの設定で署名方式 A と B を許可している場合と、A だけを許可している場合では、B の解析器へ進める経路が異なる可能性がある。また、認証前の状態では管理操作へ進む経路が閉じられていても、認証後にはその経路が利用可能になることがある。ここでの実行状態は、対象とする処理区間に適用される状態条件を意味し、状態遷移そのものを含む経路は、その遷移条件も考慮して評価する。
外部入力の入口集合を \(S\subseteq V\) とし、入口から一連の遷移を通じて到達できる頂点集合を \(R(c,q)\) と定義する。記号 \(s\leadsto v\) は、入口 \(s\) から処理 \(v\) へ至る実行可能な経路が存在することを表す。
\[ R(c,q)=\{v\in V\mid \exists s\in S,\ s\leadsto v\text{ in }G_{c,q}\}. \]
この式は、外部入力の入口のいずれかから到達できる処理を集めたものである。例えば、認証前の状態を \(q_{\mathrm{pre}}\) とすると、認証要求の受信処理や公開鍵の種類を識別する処理は、通常、認証前の到達可能集合に含まれる。無効化された署名方式の詳細な解析器もこの集合に含まれるなら、未認証のクライアントが与えた入力によって、その解析器を実行できる経路が存在する。一方、認証成功後にだけ実行される管理操作は、認証前の状態に限定した到達可能集合には含まれない。
到達可能集合は、特定の試験で実際に呼び出された関数の一覧とは異なる。ある試験で解析器が実行されなかったとしても、別の入力によって実行される経路が存在する可能性がある。例えば、通常の公開鍵データでは早期に拒否されても、鍵の種類を申告する情報と内部データが一致しない入力では、別の解析処理へ分岐する場合がある。到達可能性を判断するには、特定の入力による実行履歴に加え、分岐条件、入力の制約、設定による遷移の変化を確認する必要がある。逆に、単純な関数呼び出し関係だけから構成したグラフには、実際には成立しない経路が含まれる場合があるため、到達可能性の評価結果はグラフの構成精度にも依存する。
さらに、仕様と設定から見て外部入力から実行される必要のない処理集合を \(D(c,q)\) と定義する。例えば、署名方式 B が禁止されている場合でも、受信データから方式を識別するための処理は必要になる。一方、B に固有の署名検証や詳細な鍵解析が許可判定のために不要なら、それらは認証前に実行される必要のない処理として分類できる。不要であるにもかかわらず到達可能な処理は、二つの集合の共通部分として記述できる。
\[ U(c,q)=R(c,q)\cap D(c,q). \]
この式では \(R\) が実際に到達可能な処理、\(D\) が仕様上到達する必要のない処理、\(U\) が両方に含まれる処理を表す。設定によって利用を禁止された機能についても、その機能に固有のすべての処理を直ちに \(D\) へ分類するわけではない。入力を識別するために必要な解析処理があれば、その処理の実行は仕様上許容される場合がある。どの処理を不要とするかを判定する際には、許可判定に必要な処理と、許可された後にだけ必要になる処理を区別する必要がある。
| 処理の分類 | 到達可能集合 \(R(c,q)\) | 不要な処理集合 \(D(c,q)\) | 評価結果 |
|---|---|---|---|
| 認証要求の受信処理 | 未認証の入力から到達できる。 | 認証要求の受付に必要なため含まれない。 | 必要な処理として実行経路に残る。 |
| 署名方式の識別処理 | 許可判定前に実行されるため到達できる。 | 許可判定に必要な範囲では含まれない。 | 禁止対象を識別するために必要な処理となる。 |
| 禁止された署名方式の詳細な解析処理 | 許可判定前に呼び出される実装では到達できる。 | 許可判定に不要であれば含まれる。 | 両集合に含まれ、\(U(c,q)\) の要素となる。 |
| 認証成功後の管理処理 | 認証前の状態では到達できない。 | 認証前に不要な処理として分類できる。 | 不要な処理であっても到達不能なら \(U(c,q)\) には含まれない。 |
この分類によって、コードが存在すること、外部入力から実行できること、その実行が仕様上必要であることを区別できる。例えば、禁止された署名方式の解析器がプログラム内に残っていても、未認証のクライアントから到達できなければ、その状態における不要な到達可能集合には含まれない。一方、許可判定前に解析器が実行される経路があれば、その解析器が正常に認証を拒否する実装であっても、不要な到達可能性として評価される。
無効化した機能について \(U(c,q)=\varnothing\) が成立するなら、定義された不要な処理への経路は、その設定と状態の下では存在しないことになる。ただし、この結論は \(D(c,q)\) に含めた処理と、評価対象の設定・状態・入力条件の範囲に依存する。不要な処理の分類に漏れがあれば、集合が空でも実際には不要な経路が残り得る。また、少数の入力による動的な実行確認だけでは、全入力に対する到達不能を証明できない。対象となる分岐条件を十分に解析し、必要に応じて静的解析と動的検証を組み合わせることで、到達可能集合の評価精度を高められる。
設定値だけを確認しても、実行グラフのどの辺が閉じられ、どの頂点への到達が制限されたかは分からない。設定変更の前後で到達可能集合を比較すれば、禁止対象への経路が実際に除去されたかを評価できる。特に、認証前の状態で \(U(c,q)\) に含まれる処理は、認証の成功を必要とせず、外部入力によって実行される可能性がある。到達可能性を集合として定義することで、機能が無効になったという設定上の事実を、実行経路が制限されたという検証可能な条件へ置き換えられる。
3. 許可判定の位置が実行範囲を変える
鍵を受け取る処理では、アルゴリズムの利用可否をどの段階で判定するかによって、認証前に実行される処理の範囲が変わる。例えば、サーバーが受信した公開鍵の内部構造を解析し、署名の検証処理を実行した後で、そのアルゴリズムが許可リストに含まれているかを確認する実装を考える。この場合、禁止されたアルゴリズムによる認証要求は最終的に拒否されるが、拒否までに解析器や検証器が実行される可能性がある。許可判定が処理の後段に置かれているため、禁止条件が成立しても、それ以前に実行された処理への到達を防ぐことはできない。
同じ認証要求でも、アルゴリズムを識別した直後に許可リストと照合すれば、実行経路が変わる。サーバーは受信データから判定に必要な情報を取得し、禁止されたアルゴリズムであると確定した段階で要求を拒否する。その結果、許可されたアルゴリズムにだけ必要な詳細な解析や署名検証へ進む経路を制限できる。認証結果はどちらの実装でも拒否となるが、前者では禁止対象の解析処理が実行され得るのに対し、後者ではその処理への到達を遮断できる。この差は最終応答の内容ではなく、許可判定と解析処理の実行順序から生じる。
| 処理段階 | 解析後に拒否する実装 | 必要な識別の直後に拒否する実装 |
|---|---|---|
| データの受信 | クライアントから公開鍵データを受け取る。 | クライアントから公開鍵データを受け取る。 |
| 鍵種別の識別 | 鍵種別を識別した後も詳細な解析へ進む。 | 許可判定に必要な鍵種別を識別する。 |
| 許可リストとの照合 | 鍵の解析や検証後に許可条件を確認する。 | 禁止対象に固有の詳細な処理を開始する前に許可条件を確認する。 |
| 無効な方式の解析器 | 拒否前に呼び出され、外部入力を処理する可能性がある。 | 識別結果に基づいて拒否された要求では呼び出されない。 |
| 認証結果 | 禁止されたアルゴリズムによる要求を拒否する。 | 禁止されたアルゴリズムによる要求を拒否する。 |
この表では、両方の実装が同じ認証結果を返すにもかかわらず、禁止されたアルゴリズムの解析器が実行されるかどうかに差がある。解析後に拒否する実装では、許可判定に先行する解析器が外部入力を受け付ける。その解析器に、特定の入力によって発現するメモリ操作や境界検査の欠陥が存在すれば、認証の成功を必要とせずに欠陥へ到達できる可能性がある。一方、禁止対象を詳細な解析前に拒否する実装では、その解析器を経由する攻撃経路を除去できる。ただし、受信処理や鍵種別の識別処理は引き続き外部入力を扱うため、それらの処理に残る欠陥まで除去されるわけではない。
MITRE の CWE-696 は、処理を不適切な順序で実行することによって発生する弱点を分類している[4]。許可判定が禁止対象の解析処理より後に配置されている場合、最終的な拒否が成立していても、禁止対象の解析処理を実行させる経路が残る。この経路を除去するには、拒否条件を評価できる時点と、禁止対象に固有の処理が開始される時点を特定し、その間に許可判定を配置する必要がある。処理順序を変更する目的は、単純に拒否結果を早く返すことではなく、拒否される入力が実行できる処理の範囲を縮小することにある。
ただし、許可判定をすべての解析処理より前へ移動すると、別の問題が生じる場合がある。サーバーが受信するデータには、アルゴリズムの種類を示す識別情報と、実際の公開鍵を表す内部データが含まれることがある。許可判定で外側の識別情報だけを確認し、その後の解析器が内部データから別の鍵種別を選択する実装では、判定した対象と実際に処理する対象が一致しない。例えば、外側には許可された方式 A を指定しながら、内部には禁止された方式 B のデータを含める入力を考える。外側の識別情報だけで許可を確定すると、後続の解析処理が方式 B を選択する実装では、禁止対象の解析器へ到達する経路が残る。
この現象は、許可判定を早期に実行したという事実だけでは、禁止対象への到達不能を保証できないことを示す。判定前に取得した情報と、判定後に実行する処理の対象が一致している必要がある。識別情報を申告どおりに受け入れるのか、内部データの解析によって実際の種類を確定するのか、複数の識別情報が一致することを要求するのかによって、許可判定の成立条件は変わる。特に、入力の複数の表現が異なる処理を指し得る設計では、どの表現を認可の基準にするかを明確にする必要がある。
MITRE の CWE-551 は、入力を適切に解析・正規化する前に認可判定を行うことで、判定に用いた表現と実際の処理対象が食い違い、認可を回避される場合があることを示している[5]。例えば、ある資源を参照する文字列について、認可判定時と実際の資源アクセス時で異なる正規化処理が適用されれば、判定した資源とアクセスされる資源が一致しなくなる可能性がある。公開鍵の識別情報と内部データの不一致も、判定対象と実際の処理対象の整合性を確認する必要があるという点で共通する。ただし、具体的な入力形式や解析処理は異なるため、それぞれの形式に応じた整合性検証が必要になる。
適切な処理順序は、受信したデータを無条件に許可判定へ渡すことでも、すべての解析を完了してから判定することでもない。まず、許可判定に必要な情報を、後続の処理対象と整合する形で確定する。その情報に基づいて禁止条件を評価し、拒否が確定した入力については、禁止対象に固有の詳細な処理へ進む経路を遮断する。さらに、後続の解析によって実際の鍵種別や署名方式が確定する場合には、その結果と許可条件との整合性も確認する。OWASP の認可に関する指針も、保護対象へのアクセスに対して適切な認可確認を実施する必要性を示している[6]。
この順序は、すべての認証方式で同じ関数配置になることを意味しない。判定に必要な情報が受信データの先頭部分だけで確定する場合には、詳細な解析前に拒否できる。一方、内部データを一定範囲まで解析しなければ実際の方式を確定できない場合には、その識別処理を許可判定に先行させる必要がある。前者では早期の識別情報が許可判定の根拠となり、後者では内部データから確定した情報が根拠となる。いずれの場合も、許可判定に必要な処理と、許可された方式を実際に利用するための処理を分離することで、禁止対象への不要な到達経路を制限できる。
処理順序の変更が目的どおりに機能したかを検証するには、認証結果だけでなく、拒否される入力によって実際に呼び出された処理を確認する必要がある。例えば、許可リストから除外した方式について、正常な形式の鍵、内部構造が不正な鍵、申告された種類と内部データが一致しない鍵をそれぞれ入力し、どの段階で拒否されたかを調べる。通常の入力では早期に拒否されても、内部データの不一致によって別の解析器が起動するなら、許可判定の位置だけでは到達経路を制限できていない。関数の呼び出し状況や分岐条件を照合すれば、禁止対象に固有の解析処理が実際に遮断されているかを評価できる。
最終応答が同じでも、拒否までに実行された処理が異なれば、外部入力から到達できるコードの範囲は異なる。適切な許可判定には、判定の位置と判定対象の整合性という二つの条件が必要になる。判定に必要な情報が確定する前に許可すれば、実際の処理対象との不一致が生じ得る。禁止対象の詳細な処理を実行した後で拒否すれば、その処理への到達経路が残る。判定対象を正しく確定したうえで、禁止対象に固有の処理が開始される前に拒否することが、機能の無効化を実行経路の制限として成立させる条件となる。
4. 設定の組み合わせが制限を失わせる
ソフトウェアの実行経路は、単一の設定値だけで決まるとは限らない。ある設定がアクセス制限の条件を定め、別の設定がその条件を評価するための情報の取得方法を定めている場合、二つの設定の組み合わせによって制限の成立条件が変わる。例えば、サーバーが接続元のホスト名に基づいてアクセスを拒否する機能を持ち、ホスト名の取得方法を別の設定で制御している場合を考える。拒否規則が正しく記述されていても、規則の評価に必要なホスト名を取得できなければ、管理者が意図した接続制限が成立しない可能性がある。
具体的には、特定のホスト名に一致する接続を拒否する規則を設定したサーバーで、逆引き DNS が無効になっている場合がある。逆引き DNS は、接続元の IP アドレスから対応するホスト名を問い合わせる仕組みである。サーバーが接続元の識別に逆引き DNS を使用する実装では、この機能を無効にするとホスト名を取得せず、接続元を IP アドレス文字列として扱う場合がある。その状態でホスト名を対象とした拒否規則を評価すると、規則が想定するホスト名と、実際に比較される IP アドレス文字列が一致しない。結果として、拒否対象として設定した接続が許可される可能性が生じる。
この不一致は、拒否規則の記述が失われたことによって発生するわけではない。拒否規則は設定ファイルに残り、逆引き DNS を無効にする設定も、それ自体はホスト名の取得を省略するという目的に従って動作している。しかし、拒否規則の評価が逆引き DNS によって得られる情報を前提としている場合、情報の取得方法を変更すると、規則の評価に必要な入力が失われる。直接的には比較対象の不一致が拒否規則の不成立を生み、その背後には、アクセス制御の設定と入力情報を取得する設定との依存関係がある。
ホスト名による拒否規則と逆引き DNS の関係を整理すると、次のようになる。ここでは、逆引き DNS が有効な場合には対象ホスト名が取得でき、無効な場合には IP アドレス文字列で照合する実装を想定する。
| 拒否規則 | 逆引き DNS | 照合に使用する情報 | 拒否が成立する条件 |
|---|---|---|---|
| ホスト名による拒否規則あり | 有効になっている。 | 取得したホスト名を使用する。 | 取得したホスト名が拒否規則のパターンに一致すれば拒否される。 |
| ホスト名による拒否規則あり | 無効になっている。 | IP アドレス文字列を使用する。 | ホスト名のパターンが IP アドレス文字列に一致しなければ、拒否規則は成立しない。 |
| IP アドレスによる拒否規則あり | 無効になっている。 | IP アドレス文字列を使用する。 | IP アドレスが拒否規則に一致すれば拒否される。 |
| ホスト名による拒否規則なし | 有効・無効のいずれかである。 | 設定に応じた接続元情報を使用する。 | ホスト名による拒否条件は適用されず、他のアクセス制御条件によって接続可否が決まる。 |
表から分かるように、逆引き DNS を無効にすること自体が、常にアクセス制御の欠落を生むわけではない。IP アドレスに基づく拒否規則を使用している場合には、接続元の IP アドレス文字列を取得できれば、逆引き DNS に依存せずに規則を評価できる。一方、ホスト名を前提とする拒否規則では、取得される情報の種類が変わることで、規則の意味と実際の比較処理が食い違う。どの組み合わせで制限が成立するかは、規則の記述内容、接続元情報の取得方法、取得に失敗した場合の処理によって決まる。
実際のサーバーでは、逆引き DNS が無効な場合にホスト名規則を無視する実装もあれば、必要な情報を取得できないことを理由に接続を拒否する設計も考えられる。また、逆引き DNS が有効であっても、名前解決に失敗した場合や、取得したホスト名を追加検証する場合には、異なる経路を通る可能性がある。そのため、設定の組み合わせに問題があるかどうかは、設定項目の名称や有効・無効の値だけから確定できない。対象の実装が実際にどの情報を取得し、その情報をどの拒否規則へ渡すかを確認する必要がある。
MITRE の CWE-863 は、不適切な認可によって、本来制限されるべき資源や操作へのアクセスを許してしまう弱点を分類している[7]。ホスト名による拒否規則が期待どおりに機能しない場合にも、結果として意図しない接続を許可する可能性がある。ただし、設定の相互作用によって生じる問題がすべて CWE-863 に該当するわけではない。認可の誤りに分類されるかどうかは、対象の機能、保護対象、仕様上の許可条件によって決まる。ここで共通するのは、アクセス制御の成立が、規則の存在だけでなく、規則を評価するための情報と実際の処理条件に依存していることである。
複数設定の相互作用を数理的に表すため、二つの二値設定 \(a,b\in\{0,1\}\) を考える。値 1 は設定が有効、値 0 は無効であることを表す。設定の組み合わせ \((a,b)\) に対し、評価対象となる安全制御が仕様どおり成立するとき 1、成立しないとき 0 を返す関数を \(H(a,b)\) と定義する。例えば、ホスト名による拒否規則を有効にする設定を \(a\)、逆引き DNS を有効にする設定を \(b\) とすれば、それぞれの組み合わせにおけるアクセス制御の成立を評価できる。
二つの設定の相互作用は、次の差分によって表せる。
\[ \Delta_{ab}H=H(1,1)-H(1,0)-H(0,1)+H(0,0). \]
この式では、\(H(1,1)\) が両方の設定を有効にした場合、\(H(1,0)\) と \(H(0,1)\) が一方だけを有効にした場合、\(H(0,0)\) が両方を無効にした場合の評価結果を表す。差分 \(\Delta_{ab}H\) は、一方の設定を変更した効果が、もう一方の設定状態によって変わるかどうかを測定する指標である。例えば、\(a=0\) から \(a=1\) へ変更したときの効果は、\(b=0\) の場合には \(H(1,0)-H(0,0)\)、\(b=1\) の場合には \(H(1,1)-H(0,1)\) となる。両者の差が \(\Delta_{ab}H\) であり、値が 0 以外なら、設定変更の効果が他方の設定状態に依存することを意味する。
ただし、\(H(a,b)\) の値は、各設定の組み合わせに対して何を仕様上の正常な動作とするかを定めてから評価する必要がある。例えば、ホスト名による拒否規則を無効にした状態では、その規則による拒否が行われなくても、仕様に反しているとは限らない。一方、拒否規則が有効であり、対象の接続を拒否することが要求されている状態では、規則の評価に必要な情報が失われて接続が許可されれば、仕様上の制限が成立していないことになる。設定の組み合わせごとに期待される結果を定義せず、単に拒否件数や許可件数を比較するだけでは、安全制御の正しさを評価できない。
また、相互作用の差分が 0 以外であること自体は、欠陥の存在を意味しない。二つの設定が協調して機能を有効化する設計では、設定の効果が相互に依存することが仕様上期待される場合もある。逆に、\(\Delta_{ab}H=0\) であっても、すべての組み合わせで安全制御が仕様どおり成立するとは限らない。例えば、四つの組み合わせすべてで同じ制限が欠落していれば、差分は 0 になる。相互作用の有無を調べることと、各組み合わせの安全性を判定することは、別々の評価である。
設定の組み合わせを検証する際には、単独設定の有効性だけでなく、実際に制御へ渡される入力情報と判定結果を確認する必要がある。ホスト名による拒否規則の例であれば、規則に一致するホスト名、一致しないホスト名、逆引き DNS を無効にした状態、名前解決に失敗した状態などを区別して評価する。各条件について、接続元がどのように識別され、その情報がどの規則と比較され、最終的に接続が許可または拒否されたかを追跡する。期待結果と実際の処理経路を照合することで、設定の相互作用によって制限が失われる条件を特定できる。
この構造は、ホスト名によるアクセス制御に限られない。ある設定が機能の許可条件を定め、別の設定が判定に使用する情報や処理経路を変更する場合にも、同じ種類の依存関係が生じる。認証方式、証明書検証、入力解析、通信経路の制限などでは、複数の設定が同時に適用されたときの実行経路を確認する必要がある。個別の設定が正しく動作していても、組み合わせによって判定対象や入力情報が変われば、管理者が意図した制限が成立しない場合がある。設定の有効性は、各項目の値だけでなく、それらが同時に成立する状態で、必要な情報が取得され、期待する判定が実際に実行されるかによって評価される。
5. 不要な処理だけを到達不能にする
攻撃対象領域を縮小する際には、禁止された機能に関連する処理を到達不能にすることと、許可された機能の動作を維持することを両立させる必要がある。例えば、サーバーが複数の署名アルゴリズムに対応しており、運用環境によって許可する方式を切り替えられる場合を考える。ある環境では署名方式 A だけを許可し、別の環境では A と B の両方を許可しているとする。このとき、方式 B の解析器をプログラムから一律に削除すれば、B を禁止している環境では不要な処理を減らせるが、B を必要とする環境では正当な認証要求まで処理できなくなる。設定に応じて不要な経路を閉じ、許可された環境では必要な処理を実行できる構成が求められる。
この制約は、攻撃対象領域を単純に縮小することと、ソフトウェアの機能を保存することが異なる評価軸であるために生じる。例えば、公開鍵解析器の呼び出しをすべて禁止すれば、その解析器への到達経路は消える。しかし、公開鍵認証そのものが動作しなくなれば、必要な機能を失う。一方、許可された署名方式では従来どおり解析器を実行し、禁止された方式についてだけ詳細な解析に進む前に拒否する実装であれば、必要な機能を保存しながら不要な到達経路を制限できる。修正の評価には、到達可能性の変化と、許可された要求に対する動作の変化を別々に確認する必要がある。
修正前後の到達可能性を比較するため、修正前のプログラムを \(P_0\)、修正後を \(P_1\) とする。第 2 章で定義した不要な到達可能集合について、それぞれ \(U_0(c,q)\)、\(U_1(c,q)\) と表す。ここで \(c\) は設定、\(q\) は認証前などの実行状態であり、添字 0 と 1 は修正前後を区別する。比較する際には、同じ設定と状態を使用し、不要と判定する処理の仕様上の基準もそろえる必要がある。その条件で修正後の集合が修正前の集合に含まれるなら、新たに到達可能となる不要な処理を増やしていないことになる。
\[ U_1(c,q)\subseteq U_0(c,q). \]
この包含関係は、修正後に到達可能な不要処理が、修正前に存在した不要処理の範囲内に収まることを表す。例えば、修正前に禁止された方式 B の鍵解析器と署名検証器の両方へ到達でき、修正後にはどちらにも到達できなくなった場合、対象の不要な到達可能集合は縮小する。一方、解析器への経路を閉じた代わりに、別の経路から検証器を直接呼び出せるようになれば、単純な経路変更だけでは十分とはいえない。修正前後の集合を比較することで、特定の経路を除去したという事実と、不要な処理全体への到達可能性を縮小したという事実を区別できる。
ただし、集合の包含関係だけでは、実際に到達可能性が減少したことまでは保証されない。\(U_1(c,q)=U_0(c,q)\) でも包含関係は成立するためである。少なくとも一つの不要な処理を到達不能にしたことを表すには、修正後の集合が修正前の真部分集合となる必要がある。また、同じ処理への到達経路が複数存在する場合、一つの経路を除去しても、その処理が到達可能集合に残ることがある。関数単位の到達可能集合を縮小することと、同じ関数へ至る経路の本数を減らすことは異なる。どちらを評価するかは、攻撃対象領域の定義に応じて決める必要がある。
不要な到達経路の縮小に加え、許可された入力について必要な機能の振る舞いが保存されることも条件となる。例えば、方式 A が許可されている環境では、修正前に成功していた正当な認証要求が修正後にも成功し、認証後の権限や接続状態など、仕様上必要な状態変化が維持されなければならない。方式 B が許可されている環境でも同様に、B の解析器と署名検証器が必要な条件で実行される必要がある。拒否経路だけを変更したつもりでも、共通の鍵解析処理や許可判定を変更すれば、正常な認証経路に影響する可能性がある。
修正前後で保存すべき振る舞いを数式で表すため、当該設定で許可される入力集合を \(X_{\mathrm{allowed}}\) とする。さらに、プログラムの実行結果から、仕様上保存すべき応答と状態変化を取り出す関数を \(\operatorname{Obs}\) と定義する。修正前後のプログラムについて、理想的な互換性条件は次のようになる。
\[ \forall x\in X_{\mathrm{allowed}},\quad \operatorname{Obs}(P_0(x))=\operatorname{Obs}(P_1(x)). \]
この式は、許可されたすべての入力 \(x\) に対して、修正前後の観測可能な振る舞いが一致することを要求している。ただし、ここで一致を要求するのは、仕様上保存すべき性質である。例えば、認証の成否、認証後に与えられる権限、必要な状態遷移などは互換性の評価対象になる。一方、内部で呼び出す関数の順序や、不要な解析器が呼び出されなくなったこと自体は、修正によって変化することが期待される。内部実装まで完全に一致させる条件にすると、到達経路を変更する目的と矛盾してしまう。
この互換性条件には、評価対象となる設定を固定するという前提がある。方式 B を禁止した環境では、B による要求が拒否されることが期待され、B を許可した環境では、正当な要求が正常に処理されることが期待される。同じ入力でも設定によって期待される結果が変わるため、異なる設定間の応答をそのまま比較しても互換性は評価できない。修正前後で同じ設定、同じ認証状態、同じ入力条件を使用し、その条件において保存すべき振る舞いを比較する必要がある。
また、数式の全称条件は、許可された入力集合のすべての要素について振る舞いの保存を要求する。しかし、実際の回帰テストで実行できる入力は有限個であり、鍵の形式、アルゴリズムの種類、証明書の構造、設定の組み合わせなどによって検証対象は増える。正常な公開鍵で認証が成功したという試験結果だけでは、すべての許可された入力について互換性が維持されたことにはならない。試験で確認できた範囲と、仕様や静的解析によって保証できる範囲を区別して評価する必要がある。
不要な到達経路の縮小と必要な機能の保存を確認するには、修正によって影響を受ける条件を分けて検証することが有効である。
| 検証対象 | 確認する条件 | 確認できる範囲 |
|---|---|---|
| 拒否経路 | 無効な署名方式の要求について、固有の解析器や検証器が起動する前に拒否される。 | 試験した入力について、不要な処理が実行されなかったことを確認できる。 |
| 許可経路 | 有効な署名方式の認証結果と、仕様上必要な状態変化が維持される。 | 試験した設定と入力について、必要な機能の互換性を確認できる。 |
| 設定の組み合わせ | 署名方式の許可リスト、証明書の検証条件、接続条件などを組み合わせても、期待する許可・拒否が成立する。 | 列挙した設定の組み合わせについて、制限と正常動作の成立を確認できる。 |
| 静的な経路解析 | 許可判定を迂回して禁止対象の処理に到達する別経路の有無を調べる。 | 解析で考慮した制御フロー、入力条件、設定状態の範囲で到達可能性を評価できる。 |
拒否経路の試験では、禁止された署名方式を指定した正常形式の入力だけでなく、申告された鍵種別と内部データが一致しない入力や、構造が不正な入力も確認対象になる。例えば、方式 A を許可し、方式 B を禁止した状態で、外側には A を指定しながら内部には B の形式を含む鍵を送った場合を考える。最初の許可判定で A と判断されても、後続の解析器が B を処理できるなら、禁止対象への経路は残る。修正後にその入力が認証失敗となることに加え、B に固有の解析器がどの段階で呼び出されたかを調べる必要がある。
許可経路の試験では、禁止対象を早期に拒否するための条件分岐が、正当な入力を誤って拒否しないことを確認する。例えば、署名方式 A の識別情報に複数の表現が存在する場合、判定条件を過度に限定すると、従来は受け付けていた正当な形式まで拒否する可能性がある。また、公開鍵認証に証明書が使用される場合には、鍵そのものの署名方式と、証明書の署名に使用された方式が異なることもある。どの方式をどの許可条件で判定するかを誤れば、不要な経路を閉じる変更が正常な認証を妨げたり、別の禁止対象への経路を残したりする。
設定の組み合わせについても、修正前後の比較が必要になる。方式 B を禁止した状態で B の解析器へ到達できなくなっていても、別の設定を有効にした場合に同じ解析器への経路が再び開く可能性がある。例えば、通常の公開鍵認証では禁止対象を拒否していても、証明書を扱う経路では別の署名検証処理が呼び出される場合がある。許可判定が複数の経路に分散している実装では、それぞれの経路について同じ設定上の制限が適用されるかを確認する必要がある。単一の試験条件で不要な処理が実行されなかったことは、他の設定条件での到達不能を保証しない。
静的な経路解析は、動的な試験で実行されなかった経路を調べるために使用できる。例えば、禁止対象の解析器を呼び出す関数が複数存在する場合、それぞれの呼び出し元から外部入力の入口までの経路を確認する。すべての経路で許可判定が先行し、禁止条件が成立した場合には解析器へ進めないことを示せれば、特定の試験入力だけに依存しない根拠となる。ただし、関数ポインター、動的な分岐、入力内容による処理の選択などを解析モデルが十分に表現できなければ、実際の到達可能性と解析結果が一致しない場合がある。静的解析の結果も、対象とした制御フローと前提条件の範囲で解釈する必要がある。
正常系の維持と拒否経路の縮小を別々に確認する理由は、両者が異なる失敗条件を持つためである。不要な解析器が到達不能になっても、許可された署名方式による認証が失敗すれば、必要な機能の互換性を損なう。逆に、正当な認証が成功していても、禁止された署名方式の解析器へ到達できれば、不要な攻撃対象領域は残る。さらに、一つの拒否経路を除去しても別の経路が残れば、到達可能集合の縮小は限定的になる。修正が成立するには、対象とする設定・状態において不要な経路が縮小し、許可された入力に対する仕様上の振る舞いが保存されるという二つの条件を、それぞれの根拠に基づいて確認する必要がある。
6. OpenSSH では何が修正されたのか
設定によって機能を無効化しても、その機能に関連するコードが認証前に実行される場合がある。この問題を実際のソフトウェアで確認できる例が OpenSSH である。Anthropic の Frontier Red Team は、2026 年 10 月 20 日に公開した調査で、Claude を用いて 25 のオープンソースプロジェクト、合計 500 万行超のコードを分析し、493 件の問題を検出したと報告している。調査対象は、既定設定で不要なコードへ到達できる状態、複数の設定の組み合わせによって安全制御が失われる状態、認証や状態遷移などの制御より前に不要な処理が実行される状態の三種類に分類されている[8]。この 493 件は、不要な到達経路や設定上の不整合を含む検出件数であり、493 件の悪用可能な脆弱性が確認されたことを意味するものではない。
調査では、認証を必要とする 11 プロジェクトすべてから、意図せず認証前に到達可能になっているコードが発見された。具体的には、既定設定における不要な認証前の公開範囲が 93 件、認証前に処理が実行されたり状態が記録されたりする箇所が 37 件、設定の組み合わせによって認証前の安全制御が弱められる事例が 61 件報告されている。これらは直ちに悪用できる問題とは評価されていないが、認証によって保護されるはずの処理や、既定の機能に必要のない処理が、未認証の入力を受け付ける状態にあることを示している。設定された制限と実際の実行経路を照合することで、個別の脆弱性を発見する方法とは異なる観点から攻撃対象領域を評価できる。
OpenSSH では、2026 年に公開された 10.4 から 10.6 までの修正経過が、この問題を具体的に示している。OpenSSH は、ネットワーク経由で安全に遠隔接続するための SSH プロトコルを実装したソフトウェアである。サーバー側の sshd は、クライアントが認証に成功する前から通信データを受信し、認証方式や公開鍵の種類を識別する必要がある。そのため、認証前に実行できる解析処理の範囲が広がると、未認証のクライアントが入力を与えられるコードも増える。
OpenSSH 10.4 には、耐量子署名アルゴリズム ML-DSA-44 に関する試験的な実装が含まれていた。ML-DSA は量子コンピューターによる攻撃も考慮して設計されたデジタル署名方式であり、ML-DSA-44 はそのパラメーターセットの一つである。この実装は既定では利用が許可されていなかったが、Anthropic の分析では、未認証のクライアントから関連する約 4,500 行のコードへ到達できる状態だった。管理者が明示的にアルゴリズムを除外した場合にも、同じ到達経路が残っていたと報告されている。
直接の原因は、受信した公開鍵を解析する処理と、許可アルゴリズムを照合する処理の順序にあった。OpenSSH 10.4 の sshd は、クライアントから送られた鍵の種類に応じた解析処理を実行し、証明書の場合には内部に含まれる認証局の署名も検証した後で、その鍵種別が許可されているかを確認していた。認証を成功させないという設定上の制限は成立していても、禁止された方式の解析器を実行しないという制限は成立していなかった。約 4,500 行という規模は、Anthropic の計測では、既定構成の sshd における認証前コードの約 16% に相当していた。
ここでの問題は、ML-DSA-44 の実装に特定の悪用可能な欠陥が見つかったということではない。ML-DSA-44 を利用しない構成でも、その解析処理が未認証の入力を受け付ける経路に残っていた点にある。仮にその解析器に未知の欠陥が存在すれば、攻撃者は ML-DSA-44 による認証を成功させることなく、解析器へ問題のある入力を渡せる可能性がある。署名方式を無効化していることと、その署名方式の実装を攻撃者から到達不能にしていることの差が、具体的なコード規模とともに確認された。
Anthropic はこの問題を OpenSSH の開発者へ報告し、修正案を提供した。2026 年 8 月 11 日に公開された OpenSSH 10.5 では、クライアントが送信した公開鍵の種類を許可アルゴリズムと照合する処理が、鍵データの解析前へ移動された。OpenSSH の公式リリース記録にも、この変更によって認証前の攻撃対象領域から一部の鍵解析・検証経路を除外したことが記載されている[9]。禁止された鍵種別を早期に拒否することで、その鍵種別に固有の解析器を起動せずに認証要求を終了できるようにした。
ところが、10.5 の変更後も、許可判定を通過して禁止されたアルゴリズムの解析処理へ到達する経路が二つ残っていた。第一の経路は、クライアントが申告するアルゴリズム名と、送信した鍵データの内部に記録された鍵種別が一致しない場合である。10.5 の早期判定はクライアントが申告したアルゴリズム名を確認していたが、実際に呼び出す解析器は、鍵データ内部の種類名によって選択されていた。そのため、外側では許可されている ssh-ed25519 を申告しながら、内部には ML-DSA の鍵データを含めることで、最初の許可判定を通過し、ML-DSA の解析器へ進むことができた。
この経路では、許可判定の実行時点を早めたという変更自体は機能している。しかし、判定対象に使用した情報と、解析器を選択するために使用した情報が異なっていた。外側のアルゴリズム名が許可リストに含まれていても、内部データが同じアルゴリズムに対応する保証がなければ、許可判定の結果をそのまま後続の解析処理へ適用できない。第 3 章で整理した判定順序の問題に加え、判定対象と実際の処理対象の一致を保証する条件が必要だった。
第二の経路は、公開鍵証明書の内部に含まれる認証局の署名検証だった。SSH の公開鍵証明書には、利用者の公開鍵に加え、その証明書へ署名した認証局の情報が含まれる。OpenSSH 10.5 では、利用者の公開鍵に関する署名処理は許可リストによって制限されていた一方、証明書内部の認証局の公開鍵については、対応する許可条件を確認する前にデータの復元と署名検証が実行されていた。証明書形式の鍵種別は既定で利用可能だったため、攻撃者が用意した証明書を処理する際に、内部の認証局が使用する署名方式の検証器へ到達できる状態が残っていた。
この場合、クライアント自身が申告した鍵種別を正しく判定できても、証明書内部の署名方式は別の処理経路で選択される。外側の公開鍵に対する許可判定と、証明書へ署名した認証局のアルゴリズムに対する許可判定は、それぞれ異なる対象を確認する必要がある。Anthropic の報告では、この経路によって、鍵交換を完了できるクライアントから、実行ファイルに含まれる公開鍵署名検証器へ到達できる状態だった。認証局の公開鍵を復元し、その署名を検証する処理が、設定による制限より前に存在していたためである。
Anthropic は、これらの残存経路について再現用の実証コードを作成し、OpenSSH の開発者と修正を検討した。その結果、許可判定を解析器の外側に一度だけ配置する方式から、解析処理の内部で実際の鍵種別と証明書の認証局署名アルゴリズムを確認する方式へ変更された。内部データから判定対象を識別した段階で許可リストと照合し、禁止された方式については、対応するデータの復元や署名検証へ進む前に拒否する構成である。この変更により、外側の申告と内部の鍵種別が食い違う場合や、証明書内部に禁止された認証局署名方式が含まれる場合にも、不要な解析・検証処理への到達を制限できるようになった。
この修正は 2026 年 10 月 6 日に公開された OpenSSH 10.6 に取り込まれた。公式リリース記録では、鍵の解析中に実際の鍵種別と認証局の署名方式を PubkeyAcceptedAlgorithms などの許可リストへ可能な限り早期に照合し、無効化されたアルゴリズムが公開する攻撃対象領域を縮小したと説明している。また、Chris Rohlf、Claude、Anthropic Research との協力についても明記している[10]。修正対象は、署名アルゴリズムの実装そのものではなく、設定された許可条件を実際の解析・検証処理へ適用する位置と方法だった。
OpenSSH 10.4 から 10.6 までの変化を、許可判定と実行経路の関係で整理すると次のようになる。
| 段階 | 許可判定と実行経路の関係 | 残った条件または修正結果 |
|---|---|---|
| OpenSSH 10.4 | 受信した鍵を解析し、証明書では認証局の署名も検証した後で、鍵種別を許可リストと照合していた。 | 既定で無効な ML-DSA-44 に関連する約 4,500 行のコードへ認証前に到達できた。 |
| OpenSSH 10.5 | クライアントが申告した公開鍵の種類を、鍵データの解析前に許可リストと照合するよう変更した。 | 申告された種類名と内部データの種類不一致、および証明書内の認証局署名検証経路が残った。 |
| OpenSSH 10.6 | 解析中に実際の鍵種別と認証局の署名方式を識別し、対応するデータの復元や署名検証より前に許可リストと照合するよう変更した。 | 禁止された署名方式に固有の解析・検証処理への認証前到達経路をさらに縮小した。 |
表の三つの段階は、許可判定が存在するかどうかではなく、何を判定し、その結果をどの処理へ適用するかが変化した経過を示している。10.4 では、禁止された鍵種別の解析が許可判定より前に実行されていた。10.5 では許可判定を前方へ移したが、外側の申告だけでは内部の解析対象を制限できず、証明書の認証局署名を扱う経路も残った。10.6 では、実際の解析対象に対応する許可判定を解析処理へ組み込むことで、これらの経路を制限した。同じ署名アルゴリズムの許可リストを使用していても、判定対象と実行位置によって到達可能な処理が変わることが分かる。
Anthropic は、最終的な修正によって、既定構成の OpenSSH で未認証のクライアントから到達可能だったコードの約 5 分の 1 を対象外にできたと報告している。縮小したコードの大部分は、試験的に追加されていた ML-DSA 関連の実装だった。許可された認証局署名アルゴリズムを使用する証明書については、必要な解析と署名検証を引き続き実行できる一方、無効化された方式については、解析・検証前に制限が適用される。この結果は、必要な機能を保存しながら不要な到達経路を除去するという、第 5 章で定義した二つの条件に対応している。
ただし、約 5 分の 1 という数値は、Anthropic が定義した認証前の到達可能コード量に基づく縮小率である。公開鍵解析器のコード量が減少しても、残ったコードの脆弱性密度や攻撃者が利用できる入力条件が同じとは限らない。また、この調査では、未知の脆弱性を悪用した侵害の発生確率が修正前後で何%変化したかを直接測定していない。到達可能なコードの縮小は、禁止された方式の実装に未知の欠陥が存在した場合に、その欠陥へ到達する経路を制限するという意味を持つ。侵害確率や被害規模の変化は、それとは別の評価対象となる。
OpenSSH の修正経過から得られる帰結は、許可判定を早期に実行するだけで制限が完成するとは限らないということである。判定に用いる情報が、実際に選ばれる解析器や署名検証器と一致し、禁止された方式に固有の処理が実行される前に制限が適用されている必要がある。さらに、通常の公開鍵認証と証明書内の認証局署名検証のように、同じ種類の処理へ複数の経路から到達できる場合には、それぞれの経路に対して許可条件が成立することを確認しなければならない。設定によって機能を無効化したという事実を、不要なコードへの到達不能という実行時の性質へ変換するには、判定順序、判定対象、複数経路の整合性を合わせて検証する必要がある。
7. 攻撃対象領域の縮小は何を意味するか
OpenSSH の修正では、既定構成で認証前に到達可能だったコードの約 5 分の 1 が、未認証のクライアントから到達できる範囲から除外された。これは、利用を許可していない署名方式の解析器や検証器を、認証前の入力によって実行させる経路が減少したことを意味する。未知の欠陥がそれらの処理に存在していた場合、攻撃者が欠陥へ到達する機会を減らせる。一方、残された解析器や共通処理には引き続き外部入力が渡されるため、到達可能なコード量の減少を、そのままソフトウェア全体の安全性の改善率として解釈することはできない。
攻撃が成立するには、一般に複数の条件が必要になる。攻撃者が対象の処理へ到達できること、その処理に悪用可能な欠陥が存在すること、攻撃者が欠陥を発現させる入力を与えられること、さらに他の保護機構によって攻撃が阻止されないことなどである。到達可能性の縮小は、このうち処理への到達という条件を制限する。例えば、禁止された署名方式の解析器に未知の欠陥があっても、その解析器を呼び出す経路が認証前から除去されていれば、未認証の入力によってその欠陥を利用することは難しくなる。しかし、同じ解析器へ別の経路から到達できる場合や、許可された処理に別の欠陥が存在する場合には、攻撃可能性が残る。
到達可能性を定量的に扱うため、第 2 章で定義した到達可能集合 \(R(c,q)\) の各頂点 \(v\) に、非負の重み \(w_v\) を与える。重みは、その処理が攻撃対象領域の規模にどの程度寄与するかを表すための値である。例えば、各頂点を互いに重複しないコード領域として定義し、そのコード行数を重みに使用すれば、到達可能なコード量を近似できる。頂点を関数単位で定義する場合には、各関数に含まれるコード行数を対応させる方法が考えられる。ただし、共有されるコードを複数の頂点で重複して数えると、実際のコード量より大きな値になるため、測定対象と集計方法を統一する必要がある。
設定 \(c\) と実行状態 \(q\) における攻撃対象領域の代理指標を、次のように定義する。
\[ A(c,q)=\sum_{v\in R(c,q)}w_v. \]
この式は、到達可能集合に含まれる各処理の重みを合計したものである。\(R(c,q)\) は外部入力から到達可能な処理の集合、\(w_v\) は各処理の重み、\(A(c,q)\) はその合計値を表す。すべての重みを 1 とすれば、到達可能な頂点の個数を数える指標になる。各頂点のコード行数を重みとすれば、到達可能なコード量を表す指標になる。同じ到達可能集合であっても、重みの定義によって \(A(c,q)\) の値と解釈は変わるため、比較には同一の測定基準を使用する必要がある。
修正前後の代理指標をそれぞれ \(A_0\)、\(A_1\) とする。同じ設定、実行状態、コードの集計基準で比較し、\(A_0>0\) が成立する場合、到達可能領域の縮小率を次のように定義できる。
\[ \delta_A=\frac{A_0-A_1}{A_0}. \]
この式の分子は修正によって変化した到達可能領域の規模、分母は修正前の規模である。例えば、修正前に 1,000 行のコードへ到達でき、修正後には 800 行へ到達できる場合、縮小率は \(\delta_A=0.2\) となる。これは同じ測定基準で評価した到達可能コード量が 20% 減少したことを意味する。除外された 200 行に実際の欠陥が存在するかどうか、その欠陥を攻撃者が利用できたかどうかは、この数値には含まれない。
到達可能集合とコード量の関係にも注意が必要である。静的解析で関数間の呼び出し関係を調べる場合、条件分岐や入力制約を十分に評価できなければ、実際には成立しない経路まで到達可能として数えることがある。逆に、動的な実行試験で観測した関数だけを数える場合には、試験していない入力によって実行される処理が集計から漏れる可能性がある。コード行数を使用した縮小率は、対象とする入口、設定、実行状態、到達可能性の解析方法によって変わる。異なる条件で得られた縮小率を比較する場合には、測定対象の違いを確認する必要がある。
さらに、到達可能なコード量が同じでも、実際の攻撃可能性が同じとは限らない。例えば、二つの解析器がそれぞれ 1,000 行のコードで構成されている場合を考える。一方には外部入力の長さを検証せずにメモリへ書き込む欠陥があり、もう一方では入力長と境界条件が適切に検証されているとする。コード行数は同じでも、前者には特定の入力によってメモリ破壊を引き起こす可能性があり、後者については少なくとも同じ欠陥が確認されていない。コード量は入力を処理する実装の規模を表すが、欠陥の存在や攻撃の成立条件を直接測定する指標ではない。
実際の侵害が発生する確率を \(P(L)\) と表す。ここで \(L\) は、攻撃者が対象のシステムを侵害するなど、定義した損失事象が発生することを意味する。修正前後の侵害確率を \(P_0(L)\)、\(P_1(L)\) とした場合、到達可能領域が 20% 減少したという観測から、次の関係を導くことはできない。
\[ P_1(L)=0.8P_0(L). \]
この等式が成立するには、到達可能なコード量と侵害確率との間に比例関係が存在するという追加の仮定が必要になる。しかし、コードごとの欠陥の有無、入力による欠陥の発現条件、攻撃者の能力、実行環境の保護機構などは一様ではない。例えば、除外されたコードに悪用可能な欠陥が存在していなければ、そのコードを除去したことによる直接的な侵害確率の変化は限定的かもしれない。一方、除外されたコードに容易に悪用できる重大な欠陥が集中していれば、コード量の減少率を上回るリスク低減が生じる可能性もある。どちらの場合も、到達可能なコード量だけでは変化の大きさを決定できない。
また、到達可能な処理の集合を縮小しても、修正によって別の欠陥が導入される可能性は残る。例えば、許可判定を早期に実行する変更によって、判定に使用する鍵種別と実際の解析対象が一致しなくなれば、修正前には存在しなかった判定の不整合が生じ得る。第 6 章で扱った OpenSSH 10.5 の残存経路は、許可判定の位置を変更しただけでは、禁止対象への到達可能性を十分に制限できなかった例である。攻撃対象領域の縮小を安全性の改善へ結び付けるには、不要な処理への経路が実際に除去されたことに加え、修正によって新たな危険な経路や判定の欠落が生じていないことも確認する必要がある。
Anthropic の調査結果についても、報告された数値ごとに測定対象を区別する必要がある。調査では 25 プロジェクトから合計 493 件の問題が検出された。また、設定の組み合わせに関する 162 件の問題のうち、94 件では安全制御が明示的な警告なしに無効化され、残る 68 件では安全機構の挙動に不整合が見つかったと報告している。認証を必要とする 11 プロジェクトすべてからは、意図しない認証前到達が確認された。ただし、これらの問題が単独で直ちに悪用可能だったとは報告されていない[8]。
493 件という値は、研究で採用した分類と検出方法に基づく問題の件数である。設定の組み合わせに関する 162 件は、その中で報告された特定の問題群を表し、94 件と 68 件はその内訳である。一方、認証型の 11 プロジェクトすべてに問題が見つかったという結果は、問題の件数ではなく、対象プロジェクトの範囲に関する観測である。これらの数値は分母も評価単位も異なるため、単純に加算したり、同じ割合として比較したりすることはできない。また、調査対象が特定のオープンソースプロジェクトに限定されている以上、その検出率を一般のソフトウェア全体へ直接適用する根拠もない。
研究で報告された数値と、それぞれから判断できる範囲を整理すると次のようになる。
| 評価対象 | 測定した内容 | 判断できること | 判断できないこと |
|---|---|---|---|
| 検出件数 | 25 プロジェクトから検出された 493 件の問題。 | 調査対象と検出方法の範囲で、問題がどの程度報告されたかを把握できる。 | 493 件すべてが悪用可能な脆弱性であることや、一般のソフトウェア全体で同じ頻度で発生することは判断できない。 |
| 設定の相互作用 | 162 件の問題のうち、安全制御の無効化が 94 件、挙動の不整合が 68 件。 | 複数の設定の組み合わせによって、安全制御が期待どおりに成立しない事例が存在することを確認できる。 | 各問題の悪用可能性や、実際に侵害へつながる確率は判断できない。 |
| 認証前到達 | 認証型の 11 プロジェクトすべてで、意図しない認証前到達が見つかった。 | 調査した認証型プロジェクトでは、認証前の実行経路に縮小の余地が存在したことを確認できる。 | すべての認証型ソフトウェアで同じ問題が存在することや、各経路が実際に悪用可能であることは判断できない。 |
| 到達可能コード量 | OpenSSH の既定構成で、認証前に到達可能なコードの約 5 分の 1 を対象外にした。 | 研究で使用した到達可能性の評価基準において、攻撃対象領域が縮小したことを確認できる。 | 侵害確率や被害規模が同じ割合で減少したことは判断できない。 |
表の各指標は、異なる問いに対応している。検出件数は、調査対象にどのような問題がどれだけ見つかったかを表す。認証前到達は、外部からの入力が認証前にどこまで実行できるかを表す。到達可能コード量の縮小率は、修正によってその実行範囲がどの程度変化したかを表す。侵害確率は、これらの条件に加えて欠陥の存在と悪用条件を評価する必要がある。測定対象を分けることで、493 件という検出件数から実際の脆弱性件数を推定したり、コード量の縮小率からリスク低減率を推定したりする誤りを避けられる。
攻撃対象領域の縮小によって直接確認できるのは、指定した設定と実行状態において、攻撃者の入力から到達できる処理の範囲が変化したという事実である。特に、利用を許可していない機能に固有の解析器や検証器が到達不能になれば、それらの処理に未知の欠陥が存在した場合でも、除去した経路を通じて欠陥を利用することはできなくなる。ただし、必要な機能のために残された処理や、別の設定で開放される経路については、引き続き到達可能性と安全性を評価する必要がある。
OpenSSH の事例は、既定で無効化されていた署名方式の実装が認証前に公開されていた状態から、実際の鍵種別と署名方式に応じて不要な解析・検証経路を遮断する状態へ変更されたことを示している。約 5 分の 1 という縮小率は、その変更によって除外できたコードの規模を表す具体的な成果である。一方、侵害確率の変化は直接測定されていない。検出件数、到達可能なコード量、侵害確率を区別することで、攻撃対象領域を縮小したという技術的成果と、そこから確実に導ける安全性の範囲を対応させられる。
8. 設定と実行経路の一致を検証する
機能を無効化する設定を評価する際には、設定ファイルに禁止条件が記述されていることに加え、その条件が実際の処理のどの位置で適用され、どの実行経路を遮断するかを確認する必要がある。例えば、署名アルゴリズムの許可リストから特定の方式を除外した場合、その方式による認証要求が拒否されることは、機能上の制限が成立したことを示す。しかし、認証を拒否するまでに禁止対象の解析器や検証器が実行されていれば、外部入力から到達できる処理の範囲は残っている。設定が表す禁止条件と、実際の実行経路に適用された制限を区別することで、管理者の意図がどの範囲まで実装に反映されているかを評価できる。
OpenSSH の修正経過は、この区別を具体的に示している。10.4 では、利用を許可していない署名方式の解析処理へ、認証前に到達できる状態が残っていた。10.5 では、クライアントが申告した鍵種別を解析前に許可リストと照合するよう変更されたが、申告した種類名と内部データの種類が異なる場合や、証明書内部の認証局署名を検証する場合には、禁止対象の処理へ到達する経路が残った。10.6 では、実際に解析する鍵種別と認証局の署名方式を識別し、対応する解析・検証処理を実行する前に許可条件を確認するよう修正された。この経過から、許可判定が存在すること、判定を早期に実行すること、判定結果が実際の処理対象を制限することは、それぞれ異なる条件であると分かる。
これまで定義した実行グラフを使用すれば、設定による制限が成立する条件を明示できる。設定を \(c\)、認証前などの実行状態を \(q\)、その条件下で外部入力から到達可能な処理集合を \(R(c,q)\) とする。さらに、仕様上、その設定と状態で外部入力から実行される必要のない処理集合を \(D(c,q)\) と定義する。例えば、特定の署名方式が禁止されている場合、その方式を識別するために必要な処理は残る一方、禁止された方式に固有の詳細な鍵解析や署名検証は、許可判定に不要であれば \(D(c,q)\) に含まれる。
定義した不要な処理への到達経路が存在しない条件は、次のように表せる。
\[ R(c,q)\cap D(c,q)=\varnothing. \]
この式の左辺は、実際に到達可能な処理と、仕様上実行する必要のない処理の共通部分を表す。右辺の \(\varnothing\) は空集合であり、両方に属する処理が存在しないことを意味する。例えば、禁止された署名方式 B の解析器が \(D(c,q)\) に含まれていても、外部入力からその解析器へ至る経路が存在しなければ、解析器は \(R(c,q)\) に含まれず、共通部分は空になる。一方、許可リストによる拒否が解析器の実行後に行われるなら、禁止対象の解析器は両方の集合に含まれる。このとき、認証結果が拒否であっても、式の条件は成立しない。
ただし、この等式は定義した設定、状態、不要な処理集合についての到達不能性を表している。例えば、認証前の状態で禁止対象への経路が閉じられていても、認証後の管理操作や別の設定状態で同じ処理へ到達できる場合がある。また、不要な処理集合の定義から特定の解析器が漏れていれば、その解析器が実行可能でも等式は成立し得る。実行グラフの構築時に入力条件や間接的な呼び出し経路を見落とした場合にも、モデル上の到達不能性と実際のプログラムの動作が一致しない可能性がある。したがって、等式の成立範囲を判断する際には、対象の設定、実行状態、入力条件、処理の分類、経路解析の前提を明確にする必要がある。
実際の検証では、設定された禁止条件に対して、異なる入力がどの実行経路を通るかを確認する。例えば、署名方式 A を許可し、方式 B を禁止したサーバーであれば、正常な A の鍵、正常な形式の B の鍵、外側には A を申告しながら内部には B のデータを含む鍵、構造が不正な鍵などを区別して試験する。さらに、公開鍵証明書を処理する場合には、証明書に格納された利用者の公開鍵と、証明書へ署名した認証局の公開鍵を別々に確認する必要がある。利用者の鍵種別が許可されていても、認証局の署名方式が禁止されている場合には、対応する署名検証器へ到達する前に制限が適用されなければならない。
検証条件ごとに、期待する認証結果と、実際に実行される処理を分けて整理すると次のようになる。
| 検証条件 | 確認する実行経路 | 期待される結果 |
|---|---|---|
| 許可された署名方式 | 鍵種別の識別、許可判定、必要な解析と署名検証が実行されることを確認する。 | 正当な入力について、修正前に成立していた認証と必要な状態変化が維持される。 |
| 禁止された署名方式 | 許可判定が禁止対象に固有の詳細な解析や署名検証より前に行われることを確認する。 | 認証要求が拒否され、禁止対象に固有の不要な処理が実行されない。 |
| 申告した鍵種別と内部データの不一致 | 外側の識別情報と実際の解析対象の対応、および内部の鍵種別に対する許可判定を確認する。 | 種類の不一致によって禁止対象の解析器へ進む経路が開かず、不正な要求が拒否される。 |
| 証明書内の認証局署名方式 | 証明書内部の認証局署名アルゴリズムが、対応する検証処理の前に許可リストと照合されることを確認する。 | 禁止された認証局署名方式の不要な解析・検証経路が遮断される。 |
| 設定の組み合わせ | 署名方式の許可リストと関連設定を組み合わせ、各条件下で実行可能になる経路を確認する。 | 設定の組み合わせによって禁止対象への経路が意図せず開放されない。 |
| 正常系の回帰 | 許可された鍵と証明書について、解析、署名検証、認証後の処理が維持されることを確認する。 | 必要な機能の応答と状態変化が仕様上の互換性を満たす。 |
表の各条件は、異なる失敗を検出するためのものである。禁止された署名方式の正常な形式の入力を拒否できても、内部データの種類を偽装した入力によって解析器を呼び出せる可能性がある。また、通常の公開鍵認証では禁止対象を拒否できても、公開鍵証明書の認証局署名を扱う経路では別の検証器が実行される場合がある。これらの経路は同じ許可リストに関係していても、解析対象と処理の呼び出し位置が異なるため、それぞれについて禁止条件が成立することを確認する必要がある。
動的な試験では、認証結果とともに、どの解析器や検証器が呼び出されたかを観測する。例えば、禁止された方式 B の鍵を送ったとき、方式 B に固有の解析関数が実行されていなければ、その試験入力については不要な処理への到達を否定できる。しかし、試験で使用しなかった入力や設定の組み合わせについてまで、同じ結果が成立するとは限らない。特定の入力による実行履歴は、その入力で通過した経路を示す証拠であり、すべての入力について到達不能であることを直接証明するものではない。
静的な経路解析では、禁止対象の解析器や検証器を呼び出す箇所を調べ、それぞれの呼び出し元から外部入力の入口までの経路を確認する。許可判定を経由する経路であっても、その判定が実際の解析対象に対応しているかを調べる必要がある。例えば、外側の鍵種別だけを判定している場合、内部データによって別の解析器へ分岐できるなら、許可判定が存在することだけでは経路を遮断できない。証明書の内部署名を検証する経路のように、同じ種類の処理が別の呼び出し元から実行される場合には、各経路に対する許可条件の適用を確認する。静的解析と動的試験を組み合わせることで、実際に観測した動作と、実行可能な経路の構造を異なる根拠から照合できる。
不要な経路を遮断したことに加え、許可された機能の振る舞いが保存されていることも検証条件となる。例えば、署名方式 B を禁止している環境では B の詳細な解析処理を実行しないことが期待されるが、B を許可している環境では正当な認証要求を処理できる必要がある。判定条件を変更した結果、禁止された方式の解析器が到達不能になっても、許可された方式による認証まで失敗するなら、修正は必要な機能を損なっている。逆に、許可された方式の認証が正常に動作していても、禁止対象への別経路が残っていれば、攻撃対象領域の縮小は十分ではない。到達可能性の制限と正常動作の保存は、独立した検証結果として扱う必要がある。
既稿「方針を実行構造へ変換するエージェント設計」では、自然言語で記述された方針が存在しても、実行系に順序や遷移条件が組み込まれなければ、実際の動作を拘束できないことを論じた[11]。設定ファイルによる機能制限にも対応する構造がある。管理者が署名アルゴリズムを禁止する設定を記述しても、その条件を評価する処理が、禁止対象の解析器より後に配置されていれば、解析器への到達は制限されない。また、許可判定が先行していても、判定に使用する情報と後続の解析対象が一致していなければ、意図した制限が成立しない場合がある。規則や設定による制限は、実際の入力と実行経路に対応する判定機構を通じて具体化される。
ただし、設定と実行経路の一致を検証できたとしても、それによってソフトウェアのすべての安全性が保証されるわけではない。例えば、禁止された署名方式への認証前到達を除去しても、許可された方式の解析器には引き続き入力が渡される。また、モデル化していない処理経路や、認証後に実行される機能に存在する欠陥は、今回の到達不能性の評価対象とは異なる。検証によって保証できるのは、対象とした設定、実行状態、不要な処理集合について、定義した制限が成立している範囲である。この範囲を明確にすることで、設定による機能制限の成立と、システム全体の安全性を混同せずに評価できる。
OpenSSH 10.4 から 10.6 までの修正経過では、同じ署名方式の許可リストを使用していても、許可判定の位置と判定対象によって、認証前に実行できる処理の範囲が変化した。認証要求が拒否されたという結果だけでは、禁止対象の解析器が実行されたかどうかを判断できない。許可判定を前方へ移しても、申告された鍵種別と内部データが一致しなければ、別の解析器へ到達する経路が残る。さらに、証明書内部の認証局署名のように別の処理経路が存在すれば、その経路にも対応する許可条件を適用する必要がある。機能の制限が成立するためには、判定に必要な情報が正しく確定し、禁止対象に固有の処理が実行される前に拒否され、同じ処理へ至る別経路からも制限を迂回できないことが求められる。
機能を無効化したという設定上の事実は、管理者がどの機能の利用を禁止したかを示す。一方、その設定によって実際に閉じられた実行経路は、外部入力からどの処理へ到達できなくなったかを示す。両者を対応させて検証することで、機能の利用を拒否するだけの設定と、不要な解析・検証処理への到達まで遮断する設定を区別できる。機能の無効化による攻撃対象領域の縮小は、設定項目の存在や認証結果だけで判断するものではなく、設定された禁止条件の下で、不要な処理への実行経路が実際に閉じられていることによって確認される。
参考文献
- id774, AI エージェントの安全境界は改変・探索・再利用できる経路から分離する(2026-09-29). https://blog.id774.net/entry/2026/09/29/5736/
- Jerome H. Saltzer, Michael D. Schroeder, The Protection of Information in Computer Systems (1975-09). https://www.microsoft.com/en-us/research/publication/the-protection-of-information-in-computer-systems/
- OWASP, Attack Surface Analysis Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/Attack_Surface_Analysis_Cheat_Sheet.html
- MITRE, CWE-696: Incorrect Behavior Order. https://cwe.mitre.org/data/definitions/696.html
- MITRE, CWE-551: Incorrect Behavior Order: Authorization Before Parsing and Canonicalization. https://cwe.mitre.org/data/definitions/551.html
- OWASP, Authorization Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html
- MITRE, CWE-863: Incorrect Authorization. https://cwe.mitre.org/data/definitions/863.html
- Chris Rohlf, Using Claude to reduce the attack surface of code (2026-10-20). https://www.anthropic.com/research/attack-surface-reduction
- OpenSSH Project, OpenSSH 10.5 Release Notes (2026-08-11). https://www.openssh.org/txt/release-10.5
- OpenSSH Project, OpenSSH 10.6 Release Notes (2026-10-06). https://www.openssh.org/txt/release-10.6
- id774, 方針を実行構造へ変換するエージェント設計(2026-10-20). https://blog.id774.net/entry/2026/10/20/5744/