FlawOpen

flawopen.com/Teardowns/cve-2022-31150-undici-crlf-injection

● CVE-2022-31150 · CVSS 5.3 · Средний
Исследования · FlawOpen

CVE-2022-31150: CRLF-инъекция в Undici

CVE-2022-31150 позволяла недоверенным CR/LF попасть в сериализацию запросов Undici. Здесь описаны исправление и обновление.

💡 Простыми словами (ELI5)

HTTP-запрос похож на бланк с фиксированными границами строк: в каждой строке одно поле. Если без проверки скопировать текст, скрытый перевод строки может превратить остаток в новое поле. Исправление Undici проверяет значения заголовков, метод и путь до записи.

Ключевые понятия и термины

Undici
Библиотека HTTP/1.1 для Node.js; Node.js также включает версию Undici для встроенного fetch.
CRLF-инъекция
Недоверенные байты возврата каретки и перевода строки попадают в поле протокола и могут изменить границы строк.
HTTP-токен
Ограниченный набор символов для элементов протокола, например имен заголовков и методов.
Цель запроса
Путь и параметры HTTP-запроса; управляющие символы не должны менять его структуру.

Связи со стандартами

  • Ссылка CWE для слабого места, описанного в этом руководстве: CWE-93

Анализ первопричины

До исправления Undici мог сериализовать значения заголовков с недоверенными данными и недопустимыми управляющими символами. CR/LF разделяют строки; их прием может внедрить или повредить строки заголовков. Патч проверяет имена как HTTP-токены, отклоняет недопустимые символы в значениях, проверяет токен метода и запрещает управляющие символы в пути. GitHub Advisory указывает версии пакета ниже 5.8.0, а описание NVD — ниже 5.7.1. Оба источника называют 5.8.0 исправленной версией. Это инъекция в запрос HTTP-клиента; SSRF или утечка учетных данных не являются автоматическим следствием и зависят от приложения и сетевого пути.

Пошаговый сценарий атаки

Шаг 1

1. Недоверенное значение

Данные приложения попадают в заголовок, метод или путь Undici.

Шаг 2

2. Нет проверки

В уязвимых версиях недопустимые управляющие символы могли попасть в сборку запроса.

Шаг 3

3. Граница протокола

HTTP-сериализация использует границы строк; прием символов может внедрить или повредить поля.

Шаг 4

4. Исправление и ограничение

Undici 5.8.0 проверяет байты заголовков, токены метода и символы пути до сериализации; последствия зависят от контекста.

Исходный код: Уязвимый vs Защищённый вариант

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
// Важный участок сериализации в lib/core/request.js до a29a151
function serializeRequest(request, method, path, headers) {
  request.method = method;
  request.path = path;
  for (const [key, value] of Object.entries(headers)) {
    // Перед сериализацией символы протокола не проверяются.
    request.headers += `${key}: ${value}\r\n`;
  }
}
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
// Усиленный шаблон проверки из upstream-парсера запросов
const token = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
const invalidFieldValue = /[^\t\x20-\x7e\x80-\xff]/;
const invalidPath = /[^\u0021-\u00ff]/;

function validateRequestTarget(method, path) {
  if (!token.test(method)) throw new InvalidArgumentError('invalid request method');
  if (invalidPath.test(path)) throw new InvalidArgumentError('invalid request path');
}

function processHeader(request, key, value) {
  if (!token.test(key)) throw new InvalidArgumentError('invalid header key');
  if (invalidFieldValue.test(value)) throw new InvalidArgumentError(`invalid ${key} header`);
  request.headers += `${key}: ${value}\r\n`;
}

Чек-лист по защите системы для инженеров

Источники