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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-66752-HTTP-Request-Smuggling-via-Unparsed-Transfer-Encoding-Values-tiny_http- — Уведомление о безопасности: контрабанда HTTP-запросов через неразобранные значения Transfer-Encoding (tiny_http) | Kitploit
Инструменты/GitHubGitHub/theopaid/cve-2026-66752-http-request-smuggling-via-unparsed-transfer-encoding-values-tiny_http-
Анализ уязвимостейЭксплуатация веб-приложенийВеб-безопасностьСтатьи и Исследования
GitHubtheopaid/cve-2026-66752-http-request-smuggling-via-unparsed-transfer-encoding-values-tiny_http-

CVE-2026-66752-HTTP-Request-Smuggling-via-Unparsed-Transfer-Encoding-Values-tiny_http-

Уведомление о безопасности: контрабанда HTTP-запросов через неразобранные значения Transfer-Encoding (tiny_http)

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

Популярное

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

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

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

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

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

Уведомление о безопасности: контрабанда HTTP-запросов через неинтерпретируемые значения Transfer-Encoding (tiny_http)

Назначенный CVE ID: CVE-2026-66752

Сводка

tiny_http проверяет только наличие заголовка Transfer-Encoding. Он никогда не смотрит на значение. Любое значение, включая кодировки, не являющиеся chunked, и списки кодировок, последний элемент которых не chunked, приводит к тому, что тело декодируется как chunked, а Content-Length при этом отбрасывается.

Фронтенд, который корректно разбирает трансферное кодирование, будет определять границы такого запроса иначе, чем tiny_http. Два участника с двумя разными вариантами фрейминга в одном соединении — необходимое условие для контрабанды запросов. Отправка тела не в chunked-формате с не-chunked кодировкой также заставляет tiny_http завершить чтение тела с ошибкой и вообще не отправлять ответ.

Затронутые версии

URL репозитория:

https://github.com/tiny-http/tiny-http
Затронутовсе выпущенные версии вплоть до 0.12.0 включительно (2022-10-06), текущий релиз
Проверено0.6.2, 0.6.3, 0.8.0, 0.9.0, 0.10.0, 0.11.0, 0.12.0
Исправлено вна момент написания исправленной версии нет

Серьёзность

CWE-444 (Несогласованная интерпретация HTTP-запросов).

CVSS 4.0 базовый балл 6.3 (средний) CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:L/SC:L/SI:L/SA:N

Модель угроз

Удалённый неаутентифицированный клиент, отправляющий «сырой» HTTP. Никаких учётных данных или взаимодействия с пользователем не требуется.

Для смарглинга требуется, чтобы tiny_http находился за фронтендом или CDN, который передаёт Transfer-Encoding и Content-Length и корректно применяет раздел 6.1 RFC 9112, то есть считает список кодировок, последний элемент которого не chunked, не-chunked и переходит к Content-Length. Тогда этот фронтенд и tiny_http расходятся во мнении о том, где заканчивается тело.

Случай с неотвеченным запросом не требует ничего, кроме возможности подключиться.

Корневая причина

tiny_http-0.12.0/src/request.rs, строки 143–153. Заголовок находится и клонируется, но значение всегда проверяется только на наличие:

root@kitploit:~
143      // finding the transfer-encoding header
144      let transfer_encoding = headers
145          .iter()
146          .find(|h: &&Header| h.field.equiv("Transfer-Encoding"))
147          .map(|h| h.value.clone());
148  
149      // finding the content-length header
150      let content_length = if transfer_encoding.is_some() {
151          // if transfer-encoding is specified, the Content-Length
152          // header must be ignored (RFC2616 #4.4)
153          None

tiny_http-0.12.0/src/request.rs, строки 218–221, затем безусловно применяет chunked-декодер:

root@kitploit:~
218      } else if transfer_encoding.is_some() {
219          // if a transfer-encoding was specified, then "chunked" is ALWAYS applied
220          // over the message (RFC2616 #3.6)
221          Box::new(FusedReader::new(Decoder::new(source_data))) as Box<dyn Read + Send + 'static>

transfer_encoding — это Option<AsciiString>, содержащий исходное значение, и его содержимое никогда не проверяется. Раздел 6.1 RFC 9112 требует, чтобы последней кодировкой запроса была chunked, и требует от сервера отклонять сообщение в противном случае; раздел 6.3 требует отклонять запрос, содержащий одновременно Transfer-Encoding и Content-Length.

Доказательство концепции

Шаг 1. Запустите сервер, который выводит заголовки фрейминга и прочитанное тело.

root@kitploit:~
use std::io::Read;
use tiny_http::{Response, Server};

fn main() {
    let server = Server::http("127.0.0.1:8005").unwrap();
    for mut request in server.incoming_requests() {
        let te = request.headers().iter()
            .find(|h| h.field.equiv("Transfer-Encoding"))
            .map(|h| h.value.as_str().to_string());
        let cl = request.headers().iter()
            .find(|h| h.field.equiv("Content-Length"))
            .map(|h| h.value.as_str().to_string());
        let mut body = Vec::new();
        let r = request.as_reader().read_to_end(&mut body);
        println!("TE={:?} CL={:?} read={:?} body={:?}",
                 te, cl, r, String::from_utf8_lossy(&body));
        let _ = request.respond(Response::from_string("ok"));
    }
}

Шаг 2. Отправьте запрос с Transfer-Encoding: identity, соответствующим Content-Length и обычным телом. Любой фронтенд определил бы границы этого тела как пять байт hello.

root@kitploit:~
printf 'POST / HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: identity\r\nContent-Length: 5\r\n\r\nhello' | nc -w 2 127.0.0.1 8005

Результат. tiny_http декодировал как chunked тело, которое не является chunked, отбросил его и не отправил ответ. Клиент ждёт до собственного таймаута, а соединение израсходовано.

root@kitploit:~
TE=Some("identity") CL=Some("5") read=Err(Custom { kind: InvalidInput, error: DecoderError }) body=""

Шаг 3. Отправьте список кодировок, последний элемент которого не chunked.

root@kitploit:~
printf 'POST / HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked, identity\r\n\r\n5\r\nhello\r\n0\r\n\r\n' | nc -w 2 127.0.0.1 8005

Результат. tiny_http принимает его и декодирует как chunked, хотя раздел 6.1 RFC 9112 требует отклонения:

root@kitploit:~
TE=Some("chunked, identity") CL=None read=Ok(5) body="hello"

Для сравнения, только Content-Length и корректный Transfer-Encoding: chunked работают правильно и дают body="hello".

Влияние

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

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

Устранение

Разбирайте Transfer-Encoding как список, разделённый запятыми, каковым он и является, в src/request.rs около строки 144:

Требуйте, чтобы последней кодировкой была chunked для запроса с телом, и отклоняйте любую другую кодировку с кодом 400 вместо chunked-декодирования. Отклоняйте запрос, содержащий одновременно Transfer-Encoding и Content-Length, как это требует раздел 6.3 RFC 9112 для сервера, не являющегося прокси, вместо того чтобы молча игнорировать Content-Length в строке 150.

Когда чтение тела завершается ошибкой, отправляйте 400 вместо того, чтобы бросать запрос без ответа.

Скачать инструмент