← Назад к блогу

Пароль прокси утекает через HTTP-клиент: CVE в curl, libsoup и requests

В 2026 году в curl, libcurl и libsoup нашли уязвимости, из-за которых заголовок Proxy-Authorization уходит не тому прокси или прямо целевому сайту. Разбираем, в каких условиях это происходит, какие версии безопасны, как проверить свой парсер живым тестом и как ограничить ущерб, если пароль всё-таки утечёт.

📅17 октября 2026 г.
Пароль прокси утекает через HTTP-клиент: CVE в curl, libsoup и requests

Пароль от прокси обычно берегут от людей: не светят в скриншотах, не коммитят в git, держат в переменных окружения. Но в 2026 году выяснилось, что выдать его может сам HTTP-клиент. За апрель–июль вышли сразу несколько уязвимостей в curl, libcurl и libsoup, при которых заголовок Proxy-Authorization уходит не тому прокси, а то и прямо целевому сайту. Ниже разбор, в каких условиях это случается, и пошаговая проверка своего стека.

Что случилось: четыре утечки за четыре месяца

Все эти баги устроены одинаково: клиент запоминает логин и пароль одного прокси и по ошибке отправляет их дальше по цепочке.

  • CVE-2026-6253 (curl и libcurl 7.14.1–8.19.0). Если для http:// и https:// настроены разные прокси, первый требует пароль, а второй нет, то при редиректе со смены схемы curl отправит учётные данные первого прокси второму. Данные уходят в base64, то есть фактически открытым текстом. Исправлено в curl 8.20.0, выпущенном 29 апреля 2026 года. Уязвим и консольный curl, не только библиотека.
  • CVE-2026-8927 (libcurl 7.12.0–8.20.0). Приложение переиспользует один handle для нескольких запросов, прокси берутся из переменных окружения, а авторизация идёт по Digest. Тогда заголовок Proxy-Authorization для прокси A уходит прокси B, и тот может повторить его, чтобы выдать себя за вас. Исправлено в curl 8.21.0 от 24 июня 2026 года. Консольный curl не затронут. Почти такой же баг описан в CVE-2026-7168, отличие только в том, как выбирается прокси.
  • CVE-2026-12547 (libsoup, SoupAuthManager). libsoup кеширует учётные данные прокси, не привязывая их к адресу host:port. Когда настройки прокси меняются (системные параметры, WPAD), старый заголовок уходит новому прокси. Опубликовано 21 июля 2026 года, оценка низкая.
  • CVE-2026-66339 (libsoup, CONNECT-туннели). После установки CONNECT-туннеля через HTTP-прокси libsoup прикрепляет Proxy-Authorization к следующим HTTPS-запросам внутри туннеля. Заголовок видит уже целевой сервер. CVSS 6.5, опубликовано 24 июля 2026 года.

История не новая. В Python-библиотеке requests с версии 2.3.0 до 2.31.0 (CVE-2023-32681) заголовок Proxy-Authorization при редиректе на HTTPS уходил целевому серверу, если логин и пароль были вписаны прямо в URL прокси. В urllib3 до 1.26.19 и 2.2.2 (CVE-2024-37891) заголовок, выставленный вручную, а не через встроенную поддержку прокси, не вырезался при редиректе на чужой домен.

Почему это важно именно для работы с прокси

У платного прокси пароль равен деньгам. Кто его получил, тот расходует ваш трафик, пока вы не смените доступ. При оплате за гигабайты это прямой счёт, а при общем доступе на всю команду ещё и чужие действия с вашего IP.

Самые уязвимые сценарии выглядят так:

  • Парсеры и мониторинги, которые ходят по редиректам автоматически. Сайт-цель или промежуточный редирект может увести запрос на домен, который собирает заголовки.
  • Скрипты с несколькими прокси: разные прокси для разных схем, переключение прокси между запросами на одном соединении, смешение «прокси с паролем» и «прокси без пароля».
  • Долгоживущие процессы на Linux-серверах, где libcurl и libsoup приходят с системными пакетами и обновляются вместе с дистрибутивом, а не с вашим кодом.
  • Корпоративные сети с WPAD и PAC-файлами: прокси меняется без участия приложения, и именно этот случай описан в CVE-2026-12547.

Как проверить свой стек: пошагово

  1. Узнайте реальную версию libcurl, а не только консольного curl. Команда curl -V показывает обе, но приложение может быть собрано со своей копией библиотеки. Для Python с pycurl выполните python -c "import pycurl; print(pycurl.version)", для PHP вызовите curl_version(). Безопасная граница: 8.21.0 и новее либо исправленные ветки 8.20.1+, 8.16.1+ и 8.14.2+.
  2. Проверьте Python-зависимости. Выполните pip show requests urllib3. Нужны requests не ниже 2.31.0 и urllib3 не ниже 1.26.19 (ветка 1.x) или 2.2.2 (ветка 2.x). Если зависимость приезжает транзитивно, смотрите pip list внутри того же окружения, где работает парсер.
  3. Проверьте libsoup на Linux. Это касается GNOME-приложений, WebKitGTK и всего, что собрано на этом стеке. Обновите пакет через менеджер дистрибутива и сверьтесь с бюллетенем безопасности своего дистрибутива: в карточках этих CVE у Red Hat затронутыми указаны RHEL 6–10.
  4. Найдите в коде ручную установку заголовка. Поиск по Proxy-Authorization во всём репозитории. Если заголовок выставляется руками, а не через штатный механизм прокси клиента (proxies= в requests, ProxyManager в urllib3, CURLOPT_PROXYUSERPWD в libcurl), это кандидат на утечку при редиректе.
  5. Найдите переиспользование соединений при смене прокси. Один handle libcurl, одна сессия requests или один HTTP-агент, через которые по очереди идут запросы с разными прокси. Самый простой вариант исправления: отдельная сессия на каждый прокси.
  6. Отключите автоматические редиректы там, где они не нужны. В requests это allow_redirects=False, в urllib3 redirect=False, в curl не ставьте -L и CURLOPT_FOLLOWLOCATION. Тогда 3xx обрабатываются вручную, и вы сами решаете, куда идти дальше. Именно этот обходной путь дают авторы requests и urllib3.
  7. Проведите живой тест на ловушку. Поднимите у себя простой HTTP-сервер, который печатает все пришедшие заголовки, и сделайте на нём редирект на второй такой же сервер. Прогоните через свой парсер с прокси реальный сценарий, включая смену схемы с http на https. Если хоть один из серверов увидел Proxy-Authorization, утечка подтверждена на вашем коде, а не в теории.

Подводные камни

  • Docker-образы живут своей жизнью. Обновили curl на хосте, а парсер работает в контейнере со старым базовым образом. Проверять нужно внутри контейнера: docker exec <контейнер> curl -V.
  • Консольный curl и libcurl обновляются по-разному. CVE-2026-8927 консольный curl не затрагивает, а CVE-2026-6253 затрагивает и его. Свежий curl -V в терминале ничего не говорит о библиотеке, с которой собран ваш PHP или Python.
  • Digest не спасает. Да, при Digest пароль не идёт открытым текстом. Но в CVE-2026-8927 атакующему и не нужен пароль: перехваченный заголовок повторяют, пока действует nonce.
  • Пароль в URL удобен, но опасен. Утечка в requests проявлялась именно тогда, когда учётные данные вписаны в адрес прокси вида user:pass@host:port. Это не повод отказываться от формата, но повод держать библиотеки свежими.
  • Редирект может прийти не от цели. Капча-страницы, баннеры согласия, сокращатели ссылок и CDN тоже отвечают 3xx. Чем больше в краулере «следования за ссылками», тем шире поверхность атаки.

Как ограничить ущерб, если пароль всё-таки уйдёт

Полностью исключить утечку нельзя: завтра выйдет следующая CVE. Поэтому важно, сколько стоит одна утечка.

  • Один проект, один доступ. Не держите общий логин на все парсеры. В ProxyCove каждый купленный прокси получает отдельную пару логин и пароль, поэтому утёкший доступ одного скрипта не открывает трафик остальных.
  • Не держите на одном доступе больше трафика, чем нужно. Пополняйте понемногу под задачу, а не на полгода вперёд.
  • Следите за расходом. Резкий рост трафика без роста числа задач — первый признак, что вашим доступом пользуется кто-то ещё.
  • Меняйте пароль сразу при подозрении и по графику. Как это выстроить без простоя, разобрано в гайде про ротацию паролей прокси.

Какой тип прокси выбрать и при чём здесь он

Утечка не зависит от типа прокси: баг живёт в клиенте. А вот цена утечки зависит. Датацентр-прокси дешевле за гигабайт, и для парсинга простых сайтов с частыми редиректами разумно держать их отдельно от дорогого трафика. Резидентные прокси стоит отдавать задачам, где они действительно нужны, и под них заводить отдельные доступы с отключёнными автоматическими редиректами. Мобильные прокси, самые дорогие за гигабайт, имеет смысл держать в коде с минимумом сторонних зависимостей и обязательно с проверкой версий библиотек при каждой сборке.

Вывод

Пароль от прокси может утечь без взлома, без вируса и без ошибки человека: достаточно устаревшего libcurl, редиректа на чужой домен и переиспользованного соединения. Чек-лист короткий: curl и libcurl от 8.21.0, requests от 2.31.0, urllib3 от 1.26.19 или 2.2.2, свежий libsoup, отдельная сессия на каждый прокси, редиректы под контролем и один живой тест на ловушку. Плюс отдельный доступ на каждый проект, чтобы одна утечка стоила одного скрипта, а не всего баланса.