Пароль от прокси обычно берегут от людей: не светят в скриншотах, не коммитят в 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.
Как проверить свой стек: пошагово
- Узнайте реальную версию 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+. - Проверьте Python-зависимости. Выполните
pip show requests urllib3. Нужны requests не ниже 2.31.0 и urllib3 не ниже 1.26.19 (ветка 1.x) или 2.2.2 (ветка 2.x). Если зависимость приезжает транзитивно, смотритеpip listвнутри того же окружения, где работает парсер. - Проверьте libsoup на Linux. Это касается GNOME-приложений, WebKitGTK и всего, что собрано на этом стеке. Обновите пакет через менеджер дистрибутива и сверьтесь с бюллетенем безопасности своего дистрибутива: в карточках этих CVE у Red Hat затронутыми указаны RHEL 6–10.
- Найдите в коде ручную установку заголовка. Поиск по
Proxy-Authorizationво всём репозитории. Если заголовок выставляется руками, а не через штатный механизм прокси клиента (proxies=в requests,ProxyManagerв urllib3,CURLOPT_PROXYUSERPWDв libcurl), это кандидат на утечку при редиректе. - Найдите переиспользование соединений при смене прокси. Один handle libcurl, одна сессия requests или один HTTP-агент, через которые по очереди идут запросы с разными прокси. Самый простой вариант исправления: отдельная сессия на каждый прокси.
- Отключите автоматические редиректы там, где они не нужны. В requests это
allow_redirects=False, в urllib3redirect=False, в curl не ставьте-LиCURLOPT_FOLLOWLOCATION. Тогда 3xx обрабатываются вручную, и вы сами решаете, куда идти дальше. Именно этот обходной путь дают авторы requests и urllib3. - Проведите живой тест на ловушку. Поднимите у себя простой 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, отдельная сессия на каждый прокси, редиректы под контролем и один живой тест на ловушку. Плюс отдельный доступ на каждый проект, чтобы одна утечка стоила одного скрипта, а не всего баланса.
