HTTP-сервер Erlang/OTP допускает обход аутентификации и отказ в обслуживании

Erlang

В Erlang/OTP обнаружен набор уязвимостей, затронувших преимущественно встроенный HTTP-сервер inets httpd, а также несколько смежных компонентов платформы. Проблемы позволяют удалённому неаутентифицированному злоумышленнику выводить сервер из строя, обходить защиту каталогов и манипулировать HTTP-трафиком при размещении httpd за обратным прокси. Уязвимы версии OTP начиная с 17.0, для ряда проблем - начиная с более поздних веток.

Детали уязвимостей

Значительная часть найденных дефектов относится к некорректной работе httpd с установленными ограничениями. Так, сервер не применяет задокументированный лимит одновременных подключений max_clients, который по умолчанию должен составлять 150. Фактически этот предел действует только при явной настройке параметра, а в конфигурации по умолчанию httpd принимает неограниченное число соединений. Этого достаточно, чтобы исчерпать доступные процессы, память и файловые дескрипторы, просто открыв множество подключений и удерживая их. Аналогичная проблема возникает при приёме тела запроса, разбитого на фрагменты: установленный лимит max_body_size проверяется лишь после получения целого блока данных, поэтому клиент может передавать тело бесконечно, заставляя сервер накапливать его в памяти без какого-либо ограничения.

Другой вектор отказа в обслуживании связан с некорректным значением размера фрагмента в запросе с передачей данных блоками. Если заголовки уже обработаны, а затем приходит строка, не являющаяся шестнадцатеричным числом, httpd не отклоняет запрос и не закрывает соединение. Вместо этого занимается рабочий процесс сервера и ожидает данных, которые злоумышленник не отправляет, при этом таймаут запроса уже отменён. Такой запрос не требует постоянной передачи данных - достаточно одного некорректного фрагмента, после чего соединение можно просто держать открытым, занимая один рабочий слот. Повторяя операцию, атакующий блокирует всех воркеров и делает сервис недоступным для легитимных клиентов. Отдельная разновидность этой атаки - отправка валидных заголовков с большим значением Content-Length и остановка после первого байта тела. Поскольку таймер чтения тела не восстанавливается, соединение зависает навсегда. Вместе эти уязвимости образуют семейство slowloris-подобных атак, не требующих высокой пропускной способности.

Помимо проблем с доступностью, в httpd обнаружены обходы аутентификации модуля mod_auth. Один из них связан с нормализацией пути: сервер соединяет корень документа и URI после нормализации, но не схлопывает повторяющиеся слэши. Запрос к двойному слэшу, например, к пути, начинающемуся с //, нормализуется в ту же строку с двумя слэшами, файловая система же при открытии файла обрабатывает их как один. В результате проверка регулярным выражением не находит совпадения с защищённым каталогом, и файл отдаётся без запроса учётных данных. Достаточно добавить один лишний слэш перед именем каталога. Второй вариант работает на файловых системах, не различающих регистр символов, таких как Windows и macOS: мод_auth выполняет сравнение с учётом регистра, тогда как файловая система открывает файл независимо от него. Замена букв в пути к защищённому ресурсу позволяет скачать его без аутентификации. Отдельный дефект проявляется при использовании в mod_auth хранилищ dets или mnesia: все каталоги получают общее пространство имён пользователей, из-за чего учётные данные, выданные для одного каталога, подходят для доступа к другим.

Кроме того, httpd неправильно обрабатывает несколько видов HTTP-сообщений, что создаёт условия для межзапросных подделок. Сервер принимает запросы, содержащие одновременно заголовки Transfer-Encoding и Content-Length, не закрывая соединение после ответа, как того требует спецификация. Это позволяет рассинхронизировать интерпретацию границ запроса между httpd и обратным прокси и протащить второй запрос внутри первого. Аналогичный эффект достигается при помощи перевода строки с последующим пробелом перед заголовком: httpd превращает такую строку в самостоятельный заголовок, тогда как прокси, следующий стандартам, склеивает её с предыдущим. Наконец, сервер молча отбрасывает заголовки, в которых перед двоеточием есть пробел. Если прокси пропускает такой заголовок Content-Length, httpd считает длину тела нулевой, а реальные байты тела воспринимает как начало следующего запроса. Успешная эксплуатация этих проблем позволяет обходить контроль доступа на уровне прокси и отравлять ответы другим пользователям.

За пределами httpd обнаружились схожие по сути проблемы в других компонентах. В SNMP-модуле, LDAP-клиенте eldap и HTTP-клиенте httpc используется неограниченное преобразование чисел неограниченной точности из строкового представления и обратно. Некоторые из этих операций выполняются в C-коде без возможности прерывания, поэтому обработка даже умеренно большого числа, которое злоумышленник может сгенерировать дешёвой операцией, надолго занимает поток планировщика. Атака приводит к замедлению или остановке узла. Эти дефекты оценены как умеренные, но они доступны удалённо и не требуют аутентификации.

Отдельно отмечается уязвимость в TCP-драйвере inet при использовании режима упаковки {packet,4}. Из-за ошибки в вычислении длины пакета со знаком возникает переполнение буфера приёма, которое может разрушить память виртуальной машины BEAM и вызвать её аварийное завершение. Хотя точная эксплуатация для выполнения кода маловероятна, крах узла возможен при подключении к открытому порту из ненадёжной сети.

Для всех перечисленных проблем опубликованы исправления. Закрытые версии включают OTP 29.0.6, 28.5.0.6 и 27.3.4.17, а также соответствующие исправления для подпакетов inets, snmp, eldap и erts. Пользователям рекомендуется обновить Erlang/OTP до одной из указанных версий. Если обновление невозможно, стоит использовать обходные меры: явно задавать в конфигурации httpd лимиты max_clients и max_body_size, включать проверку минимальной скорости передачи данных с помощью параметра minimum_bytes_per_second и размещать перед сервером обратный прокси, который нормализует пути и отклоняет некорректные заголовки. Для защиты от проблемы в inet driver следует ограничить размер пакета опцией packet_size и не использовать режим {packet,4} на портах, доступных недоверенным клиентам.

Массовое выявление несоблюдения задокументированных ограничений и расхождений между документацией и реальным поведением сервера показывает, что даже зрелые платформы с длинной историей остаются подвержены хорошо известным классам ошибок. Особую ценность уязвимости приобретают в конфигурациях за обратным прокси, где различия в обработке HTTP между системами превращаются в практические векторы атак.

Ссылки

Комментарии: 0