"Польза" от уязвимостей
Я вообще не очень люблю ныть, когда у меня нет какого-то конкретного предложения, как починить причину нытья, но тут что-то уже клинит.
Безопасность - это важно. Важно, чтобы все писали свой код так, чтобы его нельзя было просто взломать. Важно, чтобы мы не писали в своем коде NODE_TLS_REJECT_UNAUTHORIZED. Важно, чтобы библиотеки, которые обрабатывают http-запросы, не давали возможности сделать запрос типа GET ../../../etc/passwd.
Но мне кажется, что за последнее время поиск уязвимостей в библиотеках превратился в какой-то абсурд. И мне кажется, что это может превратиться в историю про мальчика, который кричал "волки".
Рандомные примеры критических уязвимостей за последнее время:
Уязвимость в fast-redact
CVE-2025-57319 - жуткая (high severity!) уязвимость в библиотеке, которая предназначена для маскирования данных в объектах. Часто используется в системах логирования. В чем же там суть? Какой-то секьюрити-ресёрчер обнаружил prototype pollution уязвимость в одном из методов библиотеки.
Если передать в него специальным образом сконструированный объект - он может испортить глобальные прототипы всех объектов. В первую секунду ты думаешь "да, действительно неприятно, надо чтобы это исправили". Но потом начинаешь смотреть на пример того, а как же это работает.
Вот пример из самой уязвимости:
// Create a custom object
const customObject = {};
// Craft the instructions to inject a property into Object.prototype
const instructions = [
{
target: customObject,
path: ["polluted", "prototype", "constructor"],
value: true
}
];
// Call the vulnerable function with the crafted instructions
require("fast-redact/lib/modifiers").nestedRestore(instructions);
// Verify the exploit
console.log({}.polluted !== undefined ? '[POLLUTION_TRIGGERED]':'');
Кажется, что чтобы это сработало в реальности - нужно либо допустить то, что ваши разработчики - злые буратины, которые пытаются заменить поля типа constructor и prototype в объекте, либо, что еще хуже, они дают возможность внешним пользователям определять "а что же надо удалить из логов". И в том, и в другом случае - вам уже мало что поможет.
Но если посмотреть на уязвимость еще внимательнее - выяснится, что это вообще не реальный API библиотеки - это одна из внутренних функций библиотеки. Она не задокументирована и использоваться вообще не должна. А при использовании нормального внешнего API - даже злые или не очень сообразительные разработчики будут в безопасности:
const fastRedact = require("fast-redact");
const customObject = {};
const redact = fastRedact({
paths: ['polluted.prototype.constructor'],
});
console.log({}.polluted !== undefined ? '[POLLUTION_TRIGGERED]':''); // выведет ''
Да, сейчас уязвимость перевели в статус disputed. Но какой ценой? Люди уже успели наделать бесчисленное количество issue, форков, кто-то (даже поняв, что проблемы реально нет!) сделал полностью свою реализацию библиотеки.
Принесло ли это пользу человечеству? Что-то я сомневаюсь.
Уязвимость в докер-образах
Наши стандартные докер-образы основаны на node:alpine. В них почти нет лишних пакетов, и они почти совсем пустые - только код приложения и рантайм, чтобы его запустить. Да, иногда даже в совсем базовых пакетах (типа zlib или tzdata) обнаруживаются уязвимости, но это происходит не так уж и часто. Но вот недавно в кучу чатов начали стучаться. "Аларм!", "Все сломалось!", "Мы в опасности!". Сканер нашел в базовых образах критические уязвимости с высоким приоритетом, а именно CVE-2025-64756. Откуда? Из пакета glob. Откуда у нас пакет glob? Из npm. Он является базовой частью node:alpine.
А в чем там вообще уязвимость?
Оказывается, что уязвимость срабатывает только если использовать cli-интерфейс glob, запускать его с флагом --cmd. В таком случае, если злоумышленник создаст файл с именем вида $(touch pwned) и он попадет под glob - то код из имени файла успешно выполнится.
Что ж, действительно уязвимость... Но только если вы используете этот самый пакет glob как cli-утилиту. Ну и если кто-то уже понаписал в вашу файловую систему файлов с командами в их именах (а как он их туда напихал? Он уже вас взломал?)
Но у нас эта библиотека - зависимость зависимости. Никто никогда его не запускал и запускать не будет. Понятное дело, что правильным решением с точки зрения мейнтейнеров glob было бы выделить это все в отдельный пакет (что они и сделали, теперь есть отдельный glob-bin, в котором и уязвимость заодно починили). Да и вообще - виной всему любовь js-разработчиков к пакетам, в которых лежат еще пакеты, а в них - еще пакеты...
Но вот реально, являлась ли эта уязвимость критичной в нашем конкретном случае? На мой взгляд - нет.
Вместо вывода
Проблема не в этих двух конкретных уязвимостях. Это просто то, что я легко вспомнил. Почти все уязвимости, с которыми я сталкивался за последнее время, являются именно такими мутными вещами. Всегда для их эксплуатации надо сделать какие то кривые вещи со стороны самих разработчиков. Всегда для исправления ставятся максимально сжатые сроки - починить их надо уже всера.
Как я в самом начале и сказал - у меня нет какого-то решения. Уязвимости надо искать. Их надо исправлять. Но ощущение, что что-то в этом процессе фундаментально неправильно - не покидает меня.