Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
AWS-Tough-Library-Multiple-CVEs — tough のバージョン 0.20.0 より前の問題(複数の CVE) | Kitploit
ツール/GitHubGitHub/murataydemir/aws-tough-library-multiple-cves
脆弱性分析サプライチェーンセキュリティ論文と研究学習と教育
GitHubmurataydemir/aws-tough-library-multiple-cves

AWS-Tough-Library-Multiple-CVEs

tough のバージョン 0.20.0 より前の問題(複数の CVE)

リポジトリを見る

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
131年前未レビュー
共有

AWS Tough ライブラリの複数のCVE


2025年3月、AWS LabsのToughライブラリ(TUF(The Update Framework)のRustクライアント実装)において複数のセキュリティ脆弱性が公開されました。これらの問題はCVE-2025-2885、CVE-2025-2886、CVE-2025-2887、CVE-2025-2888として追跡されており、Toughバージョン0.20.0で修正されました。セキュリティエンジニアはこのドキュメントを使用して、各脆弱性の技術的詳細、コードベース内の根本原因、およびそれらを解決するパッチを理解できます。Tough < 0.20.0のすべてのユーザーは、v0.20.0以降にアップグレードすることを強くお勧めします。

CVE-2025-2885: ルートバージョンの順次検証の欠落

Toughは更新中にRoot metadataのバージョンを順番に検証できませんでした。リポジトリを制御する攻撃者(または中間者攻撃が可能な攻撃者)は、予期しないバージョン番号のルートメタデータファイルを供給し、クライアントに誤ったバージョンを取得・信頼させることができました。要するに、Toughは新しいルートメタデータのバージョンが、以前に信頼されたバージョンのちょうど1つ後であることを保証していませんでした。これはTUFの継続的な信頼の連鎖という要件に違反します。これによりロールバック攻撃またはミックスアンドマッチ攻撃が発生する可能性があり、古い(しかし正しく署名された)ルートが最新であるかのように受け入れられ、廃止された署名鍵や失効した信頼が再導入される可能性があります。

  • 勧告: GitHub Security Advisory GHSA-5vmp-m5v2-hx47 (CVE-2025-2885)
  • 影響を受けるコード: tough/src/lib.rs内のToughのルートメタデータ更新ロジック。脆弱な実装は、新しいルートのバージョンが古いルートのバージョン以上であることだけをチェックし、次の順序のバージョンであることを要求していませんでした。この欠落により、クライアントが中間のルートバージョンを順番どおりにダウンロードしなければならないというTUF仕様の規則(バージョンスキップの禁止)に違反します。

脆弱な実装: バージョン0.19.x以前では、新しいroot.jsonをダウンロードした後、Toughは署名を検証しましたが、バージョンの連続性を厳密に強制していませんでした。Toughはを許可していました。たとえば、現在信頼されているルートがバージョンNの場合、ToughはバージョンN+1をスキップして、N+2以上のバージョンを主張する新しいルートを(署名が有効である限り)受け入れていました。以下のコードスニペットは、修正前のチェックを示しています。```rust // (Prior to fix) Allow new root version to be >= old version – too permissive ensure!(root.signed.version <= new_root.signed.version, error::OlderMetadataSnafu { role: RoleType::Root, current_version: root.signed.version, new_version: new_root.signed.version });

新しいルートバージョンが信頼済みバージョン以上の任意の値であること
root@kitploit:~
攻撃者は、<b>より新しいバージョンのルートメタデータでありながら、実際には古い鍵セット</b>を提示することでこれを悪用する可能性があります。Toughはそれを更新だと思って受け入れ、[古い鍵で署名されたコンテンツを信頼](https://github.com/advisories/GHSA-5vmp-m5v2-hx47#:~:text=The%20tough%20client%20will%20trust,with%20a%20previous%20root%20role)してしまうでしょう。

<b>修正済みの実装:</b> パッチ適用済みコード(Tough 0.20.0)では、新しいルートのバージョンが古いバージョンより正確に1つだけ大きいことを明示的に要求します([コミット 0eeb60a](https://github.com/awslabs/tough/commit/0eeb60aefe27f00b65730634b788a1aafb8bf3c6) を参照)。また、新しいバージョンがより高いことを保証し(等しい場合や減少を防ぐ)、+1 を超えるジャンプを防ぎます。```rust
// (Fixed in v0.20.0) Enforce sequential root version update (new_version == old_version + 1)
ensure!(
    root.signed.version < new_root.signed.version && 
    root.signed.version.get() + 1 == new_root.signed.version.get(),
    error::OlderMetadataSnafu { 
        role: RoleType::Root, 
        current_version: root.signed.version, 
        new_version: new_root.signed.version 
    }
);

この変更により、クライアントはルートメタデータを順番どおり(N、N+1、N+2、...)にダウンロードして適用し、スキップしなくなります。ルートメタデータファイルのバージョンが正確に old_version+1 ではない場合、Tough はそれを潜在的な攻撃として扱い、更新を中止するようになりました。

  • 根本原因: 順次バージョンチェックの欠如(CWE-1288: 整合性チェック値の不適切な検証)。このコードは、新しいルートが現在のものより古い場合のみを防いでおり、予期しないジャンプには対応していませんでした。
  • 対策: パッチを含む tough = 0.20.0 にアップグレードしてください。Tough をベースにしたフォークやカスタムアップデータ―が同じ厳格なチェックを実装していることを確認してください。また、悪用の試みの兆候として、更新履歴に疑わしいルートバージョンのジャンプがないかログを監査することも推奨されます。

CVE-2025-2886: 終端委任(Terminating Delegation)が尊重されない

Tough は、TUF で定義されている「終端(terminating)」委任ターゲットロールを誤って処理していました。TUF リポジトリでは、委任を 終端(terminating) としてマークできます。つまり、ターゲットのルックアップがその委任に到達し、そこでターゲットが見つからなかった場合、検索は停止する(他の優先度の低い委任に続行しない)必要があります​。(こちら を参照)論理エラーのため、Tough はこの場合検索を終了できず、停止すべき状況でも後続の委任を検索し続けていました。これにより、優先度の低い委任を制御する攻撃者が、本来制御すべきでないターゲットのコンテンツを配信でき、意図された信頼境界を迂回する可能性がありました。​

  • アドバイザリ: GitHub Security Advisory GHSA-v4wr-j3w6-mxqc (CVE-2025-2886)​
  • 影響を受けるコード: tough/src/editor/targets.rs のターゲット検索アルゴリズム(および関連する委任解決コード)。脆弱なコードは、委任の terminating フラグを適切に処理していませんでした。Tough は、ターゲットを探して委任を反復処理する際、現在の委任が終端とマークされていて一致しなかった場合でも、TUF 仕様に反して次の委任に進んでいました。

脆弱な実装: Tough <0.20.0 では、find_target() ロジックは、ターゲットが見つかるかすべての委任ロールを探索し尽くすまで、単純にすべての可能な委任ロールを再帰的またはループで探索していました。終端ロールに遭遇しても、フラグを設定したりループを抜けたりしませんでした。旧動作の擬似コード:```rust for role in delegation_chain { if role.has_target(target) { return target_metadata; } // Missing: if role is terminating and target not found, should break. // Tough erroneously continues to next delegation. }

root@kitploit:~
つまり、上位の終端委任後に無視されるべき優先度の低い委任先が、依然として参照され、悪意のあるターゲットファイルを提供する可能性があるということです。

<b>修正された実装:</b> パッチ適用版では、終端を追跡し、検索を適切に停止するメカニズムが導入されています。終端となる委任が検出され、それにターゲットが含まれていない場合、Tough は [検索ループから即座に抜け出します](https://github.com/awslabs/tough/commit/598111f88105a707ee68b0fa06c52da7176ea96a#:~:text=%2F%2F%20we%20encountered%20a%20terminating,so%20we%20stop%20iterating%20immediately)。更新されたコードでは、終端となるロールに達するとブールフラグ(例: `terminated`)が設定され、コールスタックの上位に伝播されます。例:```rust
// If a terminating delegation was reached (and we didn't find the target there), stop searching further
if role.terminating && !permissive {
    // Mark that we encountered a terminating delegation
    *terminated = true;
    break;
}

さらに、再帰的な find_target 呼び出しには terminated フラグが追加され、終了が通知されると、上位レベルのループでは他の委任が考慮されないようになりました。Tough の RepositoryEditor::delegate_role と関連構造体も更新され、terminating 属性を保存し、検索ロジックに渡すようになりました。

  • 根本原因: コードが終端委任のセマンティクスを実装していなかった論理的欠陥 (CWE-284: 不適切なアクセス制御 – 低優先度のロールが意図された制限を上書きできる可能性) です。基本的に、終端委任に対する break がないため、許可されていないターゲットデータが考慮される可能性がありました。
  • 影響: クライアントが誤ったロールが所有するターゲットを取得する可能性がありました。具体的には、プロジェクトがターゲットのサブセットを別のパーティに委任し (オーバーライド範囲を制限するためにその委任を終端とマークした場合)、そのパーティがスコープ外のターゲットに対して任意のコンテンツを提供できる可能性がありました。これにより、TUF リポジトリの信頼階層が破壊されます。
  • 対策: 終端委任の処理を正しく実装した tough 0.20.0+ に更新してください。フォークやカスタムクライアントを維持している場合は、ターゲットの検索が終端委任で停止するようにしてください。セキュリティテスターは、古いバージョンでのみ委任悪用シナリオを試すべきです。パッチ済みバージョンは、悪意のある低優先度の応答を正しく無視します。

CVE-2025-2887: 委任されたターゲットに対する不完全なロールバック検出

Tough の スナップショットメタデータにおけるロールバック攻撃の検出ロジックは不完全でした。具体的には、Snapshot ロールを更新する際、Tough は 以前に確認されたすべてのターゲットメタデータ (委任されたターゲットを含む) が新しいスナップショットに引き続き存在し、バージョンが逆戻りしていないことを検証する必要があります (こちら を参照)。Tough はトップレベルの targets.json についてはこれを強制しましたが、委任されたターゲットメタデータファイルについては実行できませんでした。このギャップにより、攻撃者がリポジトリのスナップショットメタデータ内の委任されたターゲットファイルを検出されずに削除または巻き戻す可能性があり、クライアントが古い (または存在しない) 委任されたターゲットファイルを最新のものとして受け入れる 原因となりました。

  • 勧告: GitHub セキュリティアドバイザリ GHSA-q6r9-r9pw-4cf7 (CVE-2025-2887)
  • 影響を受けるコード: tough/src/lib.rs のスナップショット更新検証 (新しい Snapshot メタデータをロード/適用する関数)。脆弱なコードは、スナップショット内のメインの targets.json ロールの連続性のみをチェックし、スナップショットメタデータにリストされている委任ロールを反復処理して同様のチェックを実行しませんでした。

脆弱な実装: Tough <0.20.0 では、新しい snapshot.json を取得した後、クライアントは root と snapshot のロールがロールバックされていないことを確認し、特に targets.json がまだ存在することを確認していました。また、新しいスナップショット内の targets.json のバージョンが以前のバージョン以上であることも検証していました。しかし、スナップショットに委任されたターゲットが含まれている場合 (例: projects.json、user.json の委任メタデータ)、クライアントはそれらを検証しませんでした。たとえば、元のコードは次のような処理を行っていました:```rust // Pseudo-code of original snapshot rollback check (simplified) if let Some(old_targets_meta) = old_snapshot.meta.get("targets.json") { let new_targets_meta = new_snapshot.meta.get("targets.json").unwrap(); ensure!(new_targets_meta.version >= old_targets_meta.version, ...); } // (No checks for delegated target roles like "projects.json", "user.json", etc.)

root@kitploit:~
つまり、リポジトリへのアクセス権を持つ攻撃者が <b>委任メタデータファイルを削除したり、古いバージョンにロールバックしたりした</b> 場合、Toughのクライアントは気付かないでしょう – プライマリのtargets.jsonが無傷である限り。その後、クライアントはその委任から古いターゲットをダウンロードする可能性があり、それがロールバックとして拒否されるべきものであるとは気付かないのです。

<b>修正実装:</b> バージョン0.20.0では、<b>スナップショットメタデータに記載されているすべてのロール</b>に対する包括的なチェックが追加されました。新しいコードは、古いスナップショットのメタデータ内の各エントリ(すべての委任ターゲットロールを含む)を反復処理し、それぞれについて次の2点を確認します: (1) そのロールが新しいスナップショットにまだ存在すること、および (2) そのバージョンが減少していないこと。いずれかのロールが新しいスナップショットに存在しないか、以前よりも低いバージョン番号を持つ場合、更新は潜在的なロールバック攻撃として拒否されます。例えば:```rust
for (name, old_meta) in &old_snapshot.signed.meta {
    // 1. Role must appear in new snapshot
    ensure!(
        snapshot.signed.meta.contains_key(name),
        error::SnapshotRoleMissingSnafu { role: name, old_version: old_snapshot.signed.version, new_version: snapshot.signed.version }
    );
    // 2. Role’s version must not decrease
    let new_meta = snapshot.signed.meta.get(name).unwrap();
    ensure!(
        old_meta.version <= new_meta.version,
        error::SnapshotRoleRollbackSnafu { role: name, old_role_version: old_meta.version, new_role_version: new_meta.version, … }
    );
}

すべてのロールをループ処理することで(name は targets.json、delegated-role.json などの各メタデータファイル名を表します)、クライアントは委任ターゲットメタデータが削除またはリバートされた場合にそれを検出できます。SnapshotRoleMissing および SnapshotRoleRollback エラーは、ロールが消滅した場合や、そのバージョンが巻き戻された場合 に発生します。特筆すべき点として、Tough は現在、健全性チェックとして、スナップショットに少なくとも targets.json エントリが含まれていることも明示的に確認します(含まれていない場合は SnapshotTargetsMetaMissing エラーになります)。

  • 根本原因: 検証の不完全さ – Tough はロールバックチェックを委任ターゲットロールに一様に適用していませんでした。これはセキュリティコントロールの部分的な実装であり、攻撃者が悪用できるギャップを残していました(CWE-352: 認可における重要なステップの欠如。概念的には整合性検証の問題のサブセット)。コードはトップレベルのターゲットのみを保護しており、委任ロールは巻き戻らないだろうと(誤って)想定していました。
  • 影響: リポジトリを操作できる攻撃者は、クライアントに検出されることなく更新を隠したり、古い委任ターゲットデータを再導入したりできました。例えば、現在は侵害された鍵で署名された古い委任ターゲットファイルを提示でき、Tough はそのファイルのバージョンをチェックしなかったため、受け入れられてしまいました。実際には、これによりクライアントが古いコンテンツを取得したり、委任ターゲットの重要な失効情報を見逃したりする可能性がありました。(こちら を参照)
  • 対策: 完全なスナップショットロールバックチェックを実装している tough v0.20.0+ を使用してください。カスタムアップデータを維持している場合は、スナップショットにリストされているすべての信頼済みメタデータファイルについて、新しいスナップショットにもそのファイルが以前のバージョン以上のバージョン番号でリストされていることを確認してください。また、リポジトリ更新における委任ターゲットの削除についてログ記録や監査を有効にすることをお勧めします。これは稀であるべきものであり、予期せず発生した場合は悪意のある活動を示している可能性があるためです。

CVE-2025-2888: ロールバック時の不適切なタイムスタンプメタデータのキャッシュ処理

Tough は、Timestamp ロールで検出されたロールバックを誤って処理していました。TUF の Timestamp ロールは、クライアントが古いスナップショット(ロールバック)を見ていないかどうかを検出できるように、最新のスナップショットメタデータバージョンに定期的に署名します。Tough はタイムスタンプに含まれるスナップショットバージョンに対してロールバックチェックを実行していましたが、それは新しいタイムスタンプメタデータをローカルにキャッシュした後でしかありませんでした。ロールバックが検出された場合、Tough は更新を拒否しますが、無効なタイムスタンプをキャッシュ内の「最新」としてすでに永続化していました。つまり、悪意のあるタイムスタンプ(古いスナップショットバージョンを含む)がクライアントのキャッシュを汚染する可能性がありました。その後の正当な更新は、Tough にはロールバックのように見える可能性があり(キャッシュが新しいものより高いスナップショットバージョンを示すタイムスタンプを保持していたため)、正当な更新をブロック することになりました。

  • アドバイザリ: GitHub Security Advisory GHSA-76g3-38jv-wxh4 (CVE-2025-2888)
  • 影響を受けるコード: tough/src/lib.rs のタイムスタンプ更新ロジック(新しい timestamp.json をロードする関数)。核心となる問題は操作順序のバグでした。Tough は、内部のスナップショットバージョンが以前に確認したものより古くないことを完全に検証する前に、新しい Timestamp メタデータでローカルキャッシュ/状態を更新していました。

脆弱な実装: Tough <0.20.0 では、新しい timestamp.json が取得されると、クライアントはそれを解析してキャッシュに書き込み(現在の信頼済みタイムスタンプとしてマークし)、その後スナップショットバージョンのロールバックチェックを実行していました。新しいタイムスタンプのスナップショットバージョンが、以前に記録されたスナップショットバージョンより低い場合(ロールバック試行を示す)、Tough はエラーをログに記録し、その更新サイクルを拒否します – しかしキャッシュにはすでに「悪い」タイムスタンプが保持されていました。そのエラーパスではキャッシュされたエントリの削除は行われませんでした。そのため、クライアントの「信頼済み」タイムスタンプの記録がこの古いものになる可能性がありました。

例えば、最後に認識されたスナップショットバージョンが 5 だったとします。攻撃者は、スナップショットバージョン 4 に署名する Timestamp メタデータ(より高いタイムスタンプバージョン番号を持つ)を提供できます。Tough はタイムスタンプファイルを受け入れ(キャッシュし)、その後スナップショット 4 < 5 に気づいて更新をエラー終了します – しかし、この時点でキャッシュには「最新のタイムスタンプはスナップショット 4 を示す」と記録されています。次に正しいタイムスタンプ(スナップショット 5 または 6)が届くと、Tough はキャッシュされたスナップショット 4 とスナップショット 5 を比較し、別のロールバックとみなします(キャッシュのスナップショットバージョン 4 をベースラインとして誤って信頼しているため)、その結果、正当な更新さえも拒否します。AWS の速報はこのサイクルを次のように説明しています: 「クライアントは、ロールバックが検出されたときに正しく拒否されたにもかかわらず、タイムスタンプメタデータをキャッシュし…その結果 tough は後続の正当な更新を消費できなくなる。」

修正された実装: この修正により、ロールバックチェックが新しいタイムスタンプのキャッシュ前に行われることが保証され、タイムスタンプ内容のより厳格な検証が追加されました。Tough 0.20.0 では、load_timestamp() 関数が変更され、更新を完了する前に、Timestamp メタデータが適切に形成され、そのスナップショットバージョンが以前に信頼されたスナップショットバージョン以上であることを強制するようになりました。具体的には、コードは現在次のことをチェックします: (a) タイムスタンプメタデータがちょうど 1 つのエントリを持つこと(snapshot.json のみである必要があります)、(b) そのエントリが存在して解析されること、(c) 内部のスナップショットバージョンが以前のスナップショットバージョン以上であること。(こちら を参照)これらの検証がすべて合格した場合にのみ、新しいタイムスタンプは信頼済みと見なされます。追加された重要なロジックを以下に示します:```rust // Ensure the timestamp meta contains exactly one entry (the snapshot) ensure!(timestamp.signed.meta.len() == 1, error::TimestampMetaLengthSnafu { … }); let snapshot_meta = timestamp.signed.meta.get("snapshot.json"); ensure!(snapshot_meta.is_some(), error::MissingSnapshotMetaSnafu { … });

// If we have a previously trusted timestamp (old_timestamp): if let Some(old_timestamp) = old_timestamp_opt { // Check that the snapshot version in the new timestamp >= old snapshot version let old_snapshot_meta = old_timestamp.signed.meta.get("snapshot.json").unwrap(); ensure!( old_snapshot_meta.version <= snapshot_meta.unwrap().version, error::OlderSnapshotInTimestampSnafu { // details: new snapshot vs old snapshot versions snapshot_new: snapshot_meta.unwrap().version, snapshot_old: old_snapshot_meta.version, timestamp_new: timestamp.signed.version, timestamp_old: old_timestamp.signed.version } ); }

root@kitploit:~
この変更により、新しいタイムスタンプのスナップショットバージョンが以前に確認されたスナップショットバージョンより低い場合、`ensure!` は新しいタイムスタンプが信頼済みとして保存される<b>前に</b>失敗します。更新を中止するために、`OlderSnapshotInTimestamp` エラーが発生します。その結果、Tough はロールバックを検出すると、古い(正しい)タイムスタンプをキャッシュに保持し、不正なタイムスタンプが信頼済みとしてキャッシュされることはありません。これにより、拒否されたタイムスタンプ更新が将来の更新を汚染するシナリオを防ぎます。

- <b>根本原因:</b> <b>不適切な更新シーケンス</b>(CWE-367: メタデータ検証の文脈における Time-of-check Time-of-use 競合状態)。Tough のタイムスタンプにおけるスナップショットロールバックのチェックは、副作用(キャッシング)が発生した後の誤ったタイミングで実行されていました。さらに、タイムスタンプの内容(長さ)を完全に検証していなかったため、ロジックが脆弱になっていました​
- <b>影響:</b> 悪意のあるタイムスタンプ(より低いスナップショットバージョンを持つ)は、クライアントを一時的に欺き、不正な状態を保存させる可能性があります。これにより、更新メカニズムのサービス拒否が発生します。クライアントはその後、正当な更新を無効として扱うことになります(誤ったロールバック検出)​。直接のコード実行やデータ窃取はありませんが、<b>永続的な更新障害</b>は同様に危険です(例:セキュリティパッチの適用を妨げる)。([こちら](https://github.com/advisories/GHSA-76g3-38jv-wxh4#:~:text=If%20the%20tough%20client%20successfully,client%20from%20consuming%20valid%20updates) を参照)
- <b>対策:</b> tough <b>0.20.0+</b> にアップグレードしてください。パッチ適用済みバージョンはタイムスタンプロールバックイベントを安全に処理します。このバグによる更新失敗が観察された場合、修正済みクライアントで更新を再試行する前に、<b>キャッシュされたメタデータをクリア</b>(汚染されたタイムスタンプを削除)する必要があるかもしれません。一般的な慣行として、クライアントはメタデータを信頼またはキャッシュする前に常に検証すべきです。この問題はその原則を強調しています。

参考文献:
- [AWS Security Bulletin AWS-2025-007](https://aws.amazon.com/security/security-bulletins/AWS-2025-007/) – <i>tough の 0.20.0 より前のバージョンに関する問題(複数の CVE)​</i>
- [GitHub Advisory Database の CVE-2025-2885 エントリ](https://github.com/advisories/GHSA-5vmp-m5v2-hx47)
- [GitHub Advisory Database の CVE-2025-2886 エントリ](https://github.com/advisories/GHSA-v4wr-j3w6-mxqc)
- [GitHub Advisory Database の CVE-2025-2887 エントリ](https://github.com/advisories/GHSA-q6r9-r9pw-4cf7)
- [GitHub Advisory Database の CVE-2025-2888 エントリ](https://github.com/advisories/GHSA-76g3-38jv-wxh4)
- Tough v0.20.0 パッチコミット:
    - ルートバージョン修正コミット | [`awslabs/tough@​0eeb60a`](https://github.com/awslabs/tough/commit/0eeb60aefe27f00b65730634b788a1aafb8bf3c6)
    - 終端委任の修正​コミット | [`awslabs/tough@598111f`](https://github.com/awslabs/tough/commit/598111f88105a707ee68b0fa06c52da7176ea96a)
    - スナップショットロールバック修正コミット | [`awslabs/tough@3345151`](https://github.com/awslabs/tough/commit/3345151a87c358d1ce43aeb7e8b3ebea5ebdbab4)
    - タイムスタンプロールバック修正​コミット | [`awslabs/tough@9b400e1`](https://github.com/awslabs/tough/commit/9b400e1c8b7d6b9ab8009104fa7fe5884db05f18)
ツールをダウンロード