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
Vulnerability AnalysisSupply Chain SecurityPapers & ResearchLearning & Education
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의 연속 신뢰 체인 요구 사항을 위반합니다. 이로 인해 롤백 또는 혼합(mix-and-match) 공격이 발생할 수 있습니다. 이 경우 오래된(하지만 제대로 서명된) 루트가 최신인 것처럼 수락되어 폐기된 서명 키나 만료된 신뢰가 다시 도입될 수 있습니다.

  • 권고: GitHub 보안 권고 GHSA-5vmp-m5v2-hx47 (CVE-2025-2885)
  • 영향받는 코드: tough/src/lib.rs의 루트 메타데이터에 대한 Tough의 업데이트 로직입니다. 취약한 구현은 새 루트의 버전이 이전 버전보다 낮지 않은지만 확인했으며, 다음 순차 버전이어야 한다고 요구하지 않았습니다​. 이 누락은 클라이언트가 중간 루트 버전을 순서대로 다운로드해야 한다는 TUF 사양의 규칙(버전 건너뛰기 금지)을 위반합니다.

취약한 구현: 버전 0.19.x 이하에서 Tough는 새 root.json을 다운로드한 후 서명을 검증했지만 버전 연속성을 엄격하게 적용하지 않았습니다. 을 허용했습니다. 예를 들어, 현재 신뢰된 루트가 버전 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만 높을 것을 명시적으로 요구합니다([commit 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: 종료 위임이 존중되지 않음

Tough는 TUF에서 정의한 “terminating” 위임 대상(targets) 역할을 잘못 처리했습니다. TUF 저장소에서 위임은 terminating으로 표시될 수 있습니다. 즉, 대상 조회가 해당 위임에 도달했을 때 그곳에서 대상을 찾지 못하면 검색이 중단되어야 합니다(다른 우선순위가 낮은 위임으로 계속 진행되지 않아야 합니다). (여기 참조) 논리 오류로 인해 Tough는 이 경우 검색을 종료하지 못했습니다 – 중단해야 했음에도 후속 위임을 계속 검색했습니다. 이로 인해 낮은 우선순위의 위임을 제어하는 공격자가 제어해서는 안 되는 대상에 대한 콘텐츠를 제공할 수 있으며, 의도된 신뢰 경계를 우회할 수 있습니다.

  • 보안 권고: GitHub Security Advisory GHSA-v4wr-j3w6-mxqc (CVE-2025-2886)
  • 영향받는 코드: tough/src/editor/targets.rs의 대상 조회 알고리즘(및 관련 위임 해석 코드). 취약한 코드는 위임의 terminating 플래그를 제대로 처리하지 못했습니다. 대상을 검색하기 위해 위임을 반복할 때 Tough는 현재 위임이 terminating으로 표시되고 일치 항목이 없더라도 TUF 사양과 달리 다음 위임으로 진행했습니다.

취약한 구현: Tough <0.20.0에서 find_target() 로직은 대상을 찾거나 모든 가능한 위임 역할을 모두 소진할 때까지 단순히 재귀하거나 반복했습니다. terminating 역할을 만났을 때 어떤 플래그도 설정하지 않거나 루프를 중단하지 않았습니다. 이전 동작의 의사 코드:```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 속성을 저장하고 이를 탐색 로직에 전달하도록 업데이트되었습니다.

  • 근본 원인: 코드가 종결(terminating) 위임 의미론을 구현하지 않은 논리적 결함입니다 (CWE-284: 부적절한 접근 제어 – 낮은 우선순위의 역할이 의도된 제한을 재정의할 수 있음). 본질적으로 종결 위임에 대한 break가 없어서 권한 없는 대상 데이터가 고려될 수 있었습니다.
  • 영향: 클라이언트가 잘못된 역할이 소유한 대상을 가져올 수 있었습니다. 구체적으로, 프로젝트가 대상의 하위 집합을 다른 당사자에게 위임하고(재정의 범위를 제한하기 위해 해당 위임을 종결로 표시한 경우), 그 당사자는 자신의 범위 밖의 대상에 대해 임의의 콘텐츠를 계속 제공할 수 있었습니다. 이는 TUF 저장소의 신뢰 계층 구조를 깨뜨립니다.
  • 해결 방법: 종결 위임 처리를 올바르게 구현한 tough 0.20.0 이상으로 업데이트하십시오. 포크나 사용자 정의 클라이언트를 유지 관리하는 경우 대상 조회가 종결 위임에서 중단되도록 하십시오. 보안 테스터는 이전 버전에서만 위임 남용 시나리오를 시도해야 합니다. 패치된 버전은 악의적인 낮은 우선순위 응답을 올바르게 무시합니다.

CVE-2025-2887: 위임된 대상에 대한 불완전한 롤백 탐지

Tough가 스냅샷 메타데이터에서 롤백 공격을 탐지하는 로직은 불완전했습니다. 구체적으로, Snapshot 역할을 업데이트할 때 Tough는 이전에 본 모든 대상 메타데이터(위임된 대상 포함)가 여전히 존재하고 새 스냅샷에서 이전 버전으로 되돌아가지 않았는지 확인해야 합니다. (여기 참조). Tough는 최상위 targets.json에 대해서는 이를 적용했지만, 위임된 대상 메타데이터 파일에 대해서는 적용하지 못했습니다. 이 간격으로 인해 공격자는 탐지되지 않은 채 저장소의 스냅샷 메타데이터에서 위임된 대상 파일을 제거하거나 되돌릴 수 있었고, 클라이언트가 최신인 것처럼 오래된(또는 누락된) 위임 대상 파일을 수락하게 만들 수 있었습니다.

  • 권고: GitHub Security Advisory 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>하는 경우, 기본 targets.json이 온전한 한 Tough의 클라이언트는 이를 알아차리지 못한다는 의미입니다. 그러면 클라이언트는 롤백으로 거부되었어야 한다는 사실을 모른 채 해당 위임에서 오래된 target을 다운로드할 수 있습니다.

<b>수정된 구현:</b> 버전 0.20.0은 <b>스냅샷 메타데이터에 나열된 모든 역할</b>에 대한 포괄적인 검사를 추가합니다. 새 코드는 이전 스냅샷의 메타데이터에 있는 각 항목(모든 위임된 targets 역할 포함)을 반복하며 각각에 대해 두 가지를 확인합니다: (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는 이제 무결성 검사(sanity check) 차원에서 스냅샷에 최소한 targets.json 항목이 포함되어 있는지도 명시적으로 확인합니다(그렇지 않으면 SnapshotTargetsMetaMissing 오류가 발생합니다)​.

  • 근본 원인: 불완전한 검증 – Tough는 위임된 대상 역할에 롤백 검사를 일관되게 적용하지 않았습니다. 이는 보안 통제의 부분적인 구현으로, 공격자가 악용할 수 있는 허점을 남겼습니다(CWE-352: 권한 부여의 핵심 단계 누락; 개념적으로는 무결성 검증 문제의 하위 집합). 코드는 최상위 대상만 보호하고 있었으며, 위임된 역할은 회귀하지 않을 것이라고 (잘못) 가정했습니다.
  • 영향: 저장소를 조작할 수 있는 공격자는 클라이언트가 감지하지 못한 채 업데이트를 숨기거나 오래된 위임 대상 데이터를 다시 도입할 수 있습니다. 예를 들어, 현재 손상된 키로 서명된 이전 버전의 위임 대상 파일을 제시할 수 있으며, Tough가 해당 파일의 버전을 확인하지 않았기 때문에 수락되었을 것입니다. 실제로 이로 인해 클라이언트가 오래된 콘텐츠를 가져오거나 위임 대상에 대한 중요한 폐기(revocation) 정보를 놓칠 수 있습니다​. (여기 참조)
  • 해결 방안: 전체 스냅샷 롤백 검사를 구현한 tough v0.20.0+를 사용하세요​. 사용자 정의 업데이터를 유지 관리하는 경우, 스냅샷에 나열된 모든 신뢰된 메타데이터 파일에 대해 새 스냅샷에도 이전 버전 이상(>=)의 버전 번호로 해당 파일이 나열되도록 하십시오. 또한 저장소 업데이트에서 위임 대상 제거에 대한 로깅 또는 감사(auditing)를 활성화하는 것이 좋습니다. 이러한 제거는 드물어야 하며, 예기치 않게 발생하는 경우 악의적인 활동을 나타낼 수 있기 때문입니다.

CVE-2025-2888: 롤백 시 부적절한 타임스탬프 메타데이터 캐싱

Tough는 타임스탬프(Timestamp) 역할에서 감지된 롤백을 잘못 처리했습니다. TUF에서 타임스탬프 역할은 최신 스냅샷 메타데이터 버전을 주기적으로 서명하여 클라이언트가 이전 스냅샷(롤백)을 보고 있는지 감지할 수 있도록 돕습니다. Tough는 타임스탬프에 포함된 스냅샷 버전에 대한 롤백 검사를 수행하기는 했지만, 새 타임스탬프 메타데이터를 로컬에 캐싱한 후에만 수행했습니다. 롤백이 감지되면 Tough는 업데이트를 거부하지만 이미 무효한 타임스탬프를 캐시의 “최신” 항목으로 저장한 상태였습니다. 즉, 악의적인 타임스탬프(오래된 스냅샷 버전 포함)가 클라이언트의 캐시를 오염(poison)시킬 수 있었습니다. 이후의 정당한 업데이트는 Tough에게 롤백으로 보일 수 있으며(캐시가 새 버전보다 높은 스냅샷 버전을 나타내는 타임스탬프를 보유하고 있었기 때문에), 유효한 업데이트를 차단할 수 있습니다.

  • 보안 권고: GitHub 보안 권고 GHSA-76g3-38jv-wxh4 (CVE-2025-2888)
  • 영향을 받는 코드: tough/src/lib.rs의 타임스탬프 업데이트 로직(새 timestamp.json을 로드하는 함수)입니다. 핵심 문제는 처리 순서 버그(order-of-operations bug)였습니다. Tough는 내부의 스냅샷 버전이 이전에 확인한 것보다 오래되지 않았는지 완전히 검증하기 전에 새 타임스탬프 메타데이터로 로컬 캐시/상태를 업데이트했습니다.

취약한 구현(Vulnerable Implementation): Tough <0.20.0에서는 새 timestamp.json을 가져오면 클라이언트가 이를 파싱하여 캐시에 기록하고(현재 신뢰된 타임스탬프로 표시) 그런 다음 스냅샷 버전에 대한 롤백 검사를 수행했습니다. 새 타임스탬프의 스냅샷 버전이 이전에 기록된 스냅샷 버전보다 낮은 경우(롤백 시도를 나타냄) Tough는 오류를 기록하고 해당 업데이트 주기를 거부했습니다 – 그러나 캐시에는 이미 “나쁜” 타임스탬프가 저장되어 있었습니다. 해당 오류 경로에는 캐시 항목을 제거하는 처리가 없었습니다. 따라서 클라이언트가 기록한 “신뢰된” 타임스탬프가 이 오래된 것으로 바뀔 수 있었습니다.

예를 들어, 마지막으로 알려진 스냅샷 버전이 5였다고 가정해 보겠습니다. 공격자는 스냅샷 버전 4에 서명하는 타임스탬프 메타데이터(더 높은 타임스탬프 버전 번호 포함)를 제공할 수 있습니다. Tough는 타임스탬프 파일을 수락하고(캐싱) 그런 다음 스냅샷 4 < 5임을 발견하고 업데이트에서 오류를 발생시킵니다 – 그러나 이제 캐시는 “최신 타임스탬프가 스냅샷 4를 나타냄”이라고 말합니다. 다음에 올바른 타임스탬프(스냅샷 5 또는 6)가 오면 Tough는 스냅샷 5와 캐시된 스냅샷 4를 또 다른 롤백으로 간주하고(캐시의 스냅샷 버전 4를 기준선으로 잘못 신뢰하기 때문에) 유효한 업데이트조차 거부합니다. AWS 보안 게시판은 이 주기를 다음과 같이 설명합니다: “클라이언트는 롤백이 감지되었을 때 올바르게 거부되었음에도 불구하고 타임스탬프 메타데이터를 캐시하여… 이후 tough가 유효한 업데이트를 소비하지 못하게 됩니다.”​

수정된 구현(Fixed Implementation): 이 수정은 새 타임스탬프를 캐싱하기 전에 롤백 검사가 수행되도록 보장하고 타임스탬프 내용에 대한 더 엄격한 검증을 추가합니다. Tough 0.20.0에서는 load_timestamp() 함수가 수정되어, 업데이트를 마무리하기 전에 타임스탬프 메타데이터가 올바른 형식(well-formed)이며 해당 스냅샷 버전이 이전에 신뢰되었던 스냅샷 버전보다 낮지 않은지를 강제합니다. 구체적으로, 코드는 이제 다음을 확인합니다: (a) 타임스탬프 메타데이터에 정확히 하나의 항목만 있어야 하며(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 Race Condition, 메타데이터 검증 맥락에서). 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>0.20.0 이전 버전인 tough 관련 문제 (Multiple CVEs)</i>
- [CVE-2025-2885에 대한 GitHub Advisory Database 항목](https://github.com/advisories/GHSA-5vmp-m5v2-hx47)
- [CVE-2025-2886에 대한 GitHub Advisory Database 항목](https://github.com/advisories/GHSA-v4wr-j3w6-mxqc)
- [CVE-2025-2887에 대한 GitHub Advisory Database 항목](https://github.com/advisories/GHSA-q6r9-r9pw-4cf7)
- [CVE-2025-2888에 대한 GitHub Advisory Database 항목](https://github.com/advisories/GHSA-76g3-38jv-wxh4)
- Tough v0.20.0 패치 커밋:
    - 루트 버전 수정 커밋 | [`awslabs/tough@​0eeb60a`](https://github.com/awslabs/tough/commit/0eeb60aefe27f00b65730634b788a1aafb8bf3c6)
    - Terminating delegations 수정 커밋 | [`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)
도구 다운로드