Skip to content
KitploitKITPLOIT
도구블로그
Log in
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
React-Router-CVE-2025-61686- — React Router의 파일 세션 저장소에서 경로 탐색 취약점인 CVE-2025-61686에 대한 상세 분석으로, 근본 원인, 공격 시나리오 및 코드 감사 결과를 포함합니다. | Kitploit
도구/GitHubGitHub/kai-one001/react-router-cve-2025-61686-
Static AnalysisVulnerability AnalysisCode AnalysisExploitationWeb SecurityLearning & Education
GitHubkai-one001/react-router-cve-2025-61686-

React-Router-CVE-2025-61686-

React Router의 파일 세션 저장소에서 경로 탐색 취약점인 CVE-2025-61686에 대한 상세 분석으로, 근본 원인, 공격 시나리오 및 코드 감사 결과를 포함합니다.

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
저장소 보기
108개월 전아직 검토되지 않음
공유

CVE-2025-61686 취약점 분석 보고서

취약점 개요

CVE ID: CVE-2025-61686
영향 받는 버전: @react-router/node 7.0.0 ~ 7.9.3
취약점 유형: 경로 순회 (Path Traversal) / 디렉터리 트래버설

취약점 원리

1. 취약점 위치

취약점은 packages/react-router-node/sessions/fileStorage.ts 파일의 getFile() 함수 및 관련 파일 작업 로직에 존재합니다.

2. 핵심 문제 분석

2.1 Session ID의 출처

packages/react-router/lib/server-runtime/sessions.ts의 267번째 줄:

async getSession(cookieHeader, options) {
  let id = cookieHeader && (await cookie.parse(cookieHeader, options));
  let data = id && (await readData(id));
  return createSession(data || {}, id || "");
}

Session ID는 cookie.parse() 메서드를 통해 Cookie에서 파싱됩니다.

2.2 Cookie 파싱 로직

packages/react-router/lib/server-runtime/cookies.ts의 decodeCookieValue() 함수에서:

async function decodeCookieValue(
  value: string,
  secrets: string[],
): Promise<any> {
  if (secrets.length > 0) {
    // 如果配置了 secrets,会验证签名
    for (let secret of secrets) {
      let unsignedValue = await unsign(value, secret);
      if (unsignedValue !== false) {
        return decodeData(unsignedValue);
      }
    }
    return null;  // 签名验证失败返回 null
  }
  
  // 如果没有配置 secrets(未签名),直接返回解码后的值
  return decodeData(value);
}

핵심 문제: cookie가 서명되지 않은 경우(secrets가 빈 배열이거나 설정되지 않은 경우) decodeCookieValue는 디코딩된 cookie 값을 직접 반환하며, 공격자가 이 값을 완전히 제어할 수 있습니다.

2.3 경로 생성 논리

packages/react-router-node/sessions/fileStorage.ts에서:

export function getFile(dir: string, id: string): string {
  // Divide the session id up into a directory (first 2 bytes) and filename
  // (remaining 6 bytes) to reduce the chance of having very large directories,
  return path.join(dir, id.slice(0, 4), id.slice(4));
}

이 함수는 session ID를 두 부분으로 나눕니다:

  • 처음 4개 문자를 디렉터리 이름으로 사용: id.slice(0, 4)
  • 나머지 문자를 파일 이름으로 사용: id.slice(4)

그런 다음 path.join()으로 경로를 결합합니다.

2.4 취약점 악용 방식

공격 시나리오: createFileSessionStorage()를 사용하고 cookie가 서명되지 않은 경우:

  1. 공격자는 악의적인 session ID를 구성할 수 있습니다. 예: ../../etc/passwd
  2. getFile() 함수 처리:
    • id.slice(0, 4) = ../.
    • id.slice(4) = /etc/passwd
    • path.join(dir, ../., /etc/passwd)
    • path.join()이 경로를 정규화하지만, dir이 이미 상대 경로이거나 가공된 경우 여전히 경로 순회가 가능할 수 있습니다.

더 정확한 악용 방식:

  • Session ID: ....//etc/passwd
    • id.slice(0, 4) = ....
    • id.slice(4) = //etc/passwd
    • 처리가 부적절하면 /etc/passwd에 접근할 수 있습니다.

또는:

  • Session ID: ../../../etc/passwd(16자)
    • id.slice(0, 4) = ../.
    • id.slice(4) = ./etc/passwd
    • path.join()의 동작과 결합하면 경로 순회가 발생할 수 있습니다.

3. 영향을 받는 작업

다음 파일 작업이 영향을 받을 수 있습니다:

  1. readData(id) - 세션 데이터를 읽을 때

    async readData(id) {
      try {
        let file = getFile(dir, id);
        let content = JSON.parse(await fsp.readFile(file, "utf-8"));
        // ...
      }
    }
    
  2. updateData(id, data, expires) - 세션 데이터를 업데이트할 때

    async updateData(id, data, expires) {
      let content = JSON.stringify({ data, expires });
      let file = getFile(dir, id);
      await fsp.mkdir(path.dirname(file), { recursive: true });
      await fsp.writeFile(file, content, "utf-8");
    }
    
  3. deleteData(id) - 세션 데이터를 삭제할 때

    async deleteData(id) {
      try {
        await fsp.unlink(getFile(dir, id));
      }
    }
    

4. 공격 영향

  1. 파일 읽기: 공격자는 서버의 임의 파일을 읽을 수 있습니다(Web 서버 프로세스의 권한에 따라 다름).
  2. 파일 쓰기: 공격자는 서버에 파일을 쓸 수 있으며, 이로 인해 다음이 발생할 수 있습니다:
    • 데이터 유출
    • 코드 삽입
    • 권한 상승
  3. 파일 삭제: 공격자는 서버의 파일을 삭제할 수 있습니다.

5. 취약점 발생 조건

다음 조건이 모두 충족되어야 합니다:

  1. createFileSessionStorage() 메서드를 사용
  2. Cookie 서명되지 않음(cookie 구성에서 secrets를 설정하지 않았거나 secrets가 빈 배열인 경우)
  3. Web 서버 프로세스에 대상 파일에 대한 읽기/쓰기 권한이 있어야 함

코드 감사 발견 사항

핵심 코드 경로

getSession(cookieHeader) 
  → cookie.parse(cookieHeader) 
    → decodeCookieValue(value, secrets)  // 未签名时直接返回 value
      → readData(id) 
        → getFile(dir, id)  // 路径拼接,存在路径遍历风险
          → fsp.readFile(file) / fsp.writeFile(file) / fsp.unlink(file)

문제의 근본 원인

  1. 입력 검증 부족: getFile() 함수는 id 매개변수에 대한 검증이나 정규화를 수행하지 않습니다.
  2. path.join()의 정규화에 의존: path.join()이 경로를 정규화하지만, 특정 상황(예: 결합 전 경로에 이미 ..가 포함된 경우)에서는 여전히 경로 순회를 허용할 수 있습니다.
  3. 서명되지 않은 cookie: 공격자가 session ID의 값을 완전히 제어할 수 있게 합니다.
도구 다운로드