Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/kai-one001/react-router-cve-2025-61686-
Статический анализАнализ уязвимостейАнализ КодаЭксплуатацияВеб-безопасностьОбучение и Образование
GitHubkai-one001/react-router-cve-2025-61686-

React-Router-CVE-2025-61686-

Подробный анализ CVE-2025-61686, уязвимости обхода пути в файловом хранилище сессий React Router, включая первопричину, сценарии атак и результаты аудита кода.

Репозиторий
27 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2025-61686 Отчет об анализе уязвимости

Обзор уязвимости

CVE ID: CVE-2025-61686
Затронутые версии: @react-router/node с 7.0.0 по 7.9.3
Тип уязвимости: Path Traversal / Directory Traversal

Принцип уязвимости

1. Местоположение уязвимости

Уязвимость находится в файле packages/react-router-node/sessions/fileStorage.ts в функции getFile() и связанной логике файловых операций.

2. Анализ основной проблемы

2.1 Источник Session ID

В файле packages/react-router/lib/server-runtime/sessions.ts, строка 267:

root@kitploit:~
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 с помощью метода cookie.parse().

2.2 Логика разбора Cookie

В функции decodeCookieValue() файла packages/react-router/lib/server-runtime/cookies.ts:

root@kitploit:~
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:

root@kitploit:~
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 уже является относительным путём или после обработки, всё ещё возможен path traversal.

Более точный способ эксплуатации:

  • 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() может привести к path traversal.

3. Затронутые операции

Следующие файловые операции могут быть затронуты:

  1. readData(id) — при чтении данных сессии

    root@kitploit:~
    async readData(id) {
      try {
        let file = getFile(dir, id);
        let content = JSON.parse(await fsp.readFile(file, "utf-8"));
        // ...
      }
    }
    
  2. updateData(id, data, expires) — при обновлении данных сессии

    root@kitploit:~
    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) — при удалении данных сессии

    root@kitploit:~
    async deleteData(id) {
      try {
        await fsp.unlink(getFile(dir, id));
      }
    }
    

4. Влияние атаки

  1. Чтение файлов: атакующий может прочитать произвольные файлы на сервере (в зависимости от прав процесса веб-сервера)
  2. Запись файлов: атакующий может записать файлы на сервере, что может привести к:
    • Утечке данных
    • Внедрению кода
    • Повышению привилегий
  3. Удаление файлов: атакующий может удалить файлы на сервере

5. Условия срабатывания уязвимости

Должны одновременно выполняться следующие условия:

  1. Используется метод createFileSessionStorage()
  2. Cookie не подписана (в конфигурации cookie не установлен secrets или secrets — пустой массив)
  3. Процесс веб-сервера имеет права на чтение/запись целевого файла

Результаты аудита кода

Ключевой путь кода

root@kitploit:~
getSession(cookieHeader) 
  → cookie.parse(cookieHeader) 
    → decodeCookieValue(value, secrets)  // при отсутствии подписи возвращает value как есть
      → readData(id) 
        → getFile(dir, id)  // конкатенация пути, риск path traversal
          → fsp.readFile(file) / fsp.writeFile(file) / fsp.unlink(file)

Корень проблемы

  1. Отсутствие проверки входных данных: функция getFile() не проверяет и не нормализует параметр id
  2. Зависимость от нормализации path.join(): хотя path.join() нормализует путь, в определённых случаях (например, когда путь до объединения уже содержит ..) всё ещё возможен path traversal
  3. Неподписанная cookie: позволяет атакующему полностью контролировать значение session ID
Скачать инструмент