Positive Development Community
3.15K subscribers
1.56K photos
268 videos
4 files
490 links
Download Telegram
«Как последнюю пятницу в уходящем году встретишь, так их все в новом и проведешь» (не факт, что народная, но похоже, что мудрость).

Всем добра, тепла, и правильно провести, не только эту пятницу, но и все предстоящие праздники и выходные 🎄❄️

А мы — уходим на каникулы до первой рабочей недели января 🙈 Не скучайте)
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
😁97🎉5💯1
🤝 По следам Ni8mare перед Рождеством

Самой громкой CVE за каникулы стала, пожалуй, брендово-трендовая-и-вот-это-всё CVE-2026-21858 aka Ni8mare, получившая CVSS 10.0 благодаря возможности развития атаки на неё до полноценного RCE. Саму уязвимость не разобрал разве что только ленивый <автор этого канала>. Вот хороший разбор с красивыми картинками и примерами кода, повторяться, теперь уже, смысла нет.

Причина этой уязвимости, тут же названная «Content-Type Confusion» теми, кому совершенно не жаль составителей таксономий, заключается в ошибках обработки HTTP-запросов с различными Content-Type заголовками в webhook-эндпоинтах n8n: сервер необоснованно доверяет данным из req.body.files, даже когда заголовок Content-Type не указывает на multipart/form-data, что позволяет атакующему подменить содержание и структуру тела запроса. Это приводит к тому, что функции обработки считают произвольно сформированные данные «загруженными файлами» и используют их для чтения файлов на сервере. Используя это и функциональность прочих модулей, доступных в n8n, атакующий может развить атаку вплоть до RCE.

Цепляет в уязвимости то, что здесь явно теряется соблюдение в коде границы доверия, но настолько неявным способом, что заметить это, просто читая код глазами или SAST'ом — не так уж и просто. Вот близкий к оригиналу псевдокод, иллюстрирующий уязвимость этого типа:

// Middleware: разбор тела запроса в вебхуке
function parseRequestBody(req) {
if (req.headers['content-type'].startsWith('multipart/form-data')) {
// Парсим форму и файлы (через, например, Formidable)
req.body = parseFormData(req); // сформирует req.body.files для файлов
} else {
// Парсим JSON или другие типы как обычное тело
req.body = parseBody(req); // напрямую десериализует тело в req.body
}
}
// Обработчик webhook формы (уязвимая версия)
app.post('/form-webhook', (req, res) => {
parseRequestBody(req);
const result = prepareFormReturnItem(req.body);
// ... дальнейшая обработка
});
// Функция обработки загруженных файлов
function prepareFormReturnItem(body) {
for (const fileId in body.files) {
// Скопировать файл из временного пути в постоянное хранилище
copyBinaryFile(body.files[fileId].filepath, uploadDir);
}
// ... вернуть результат для workflow
}

Да, copyBinaryFile как бы намекает, что это потенциально опасная операция копирования файлов. Но SAST, не знающий о деталях работы Formidable, как минимум, здесь даст фолз+, на ветке с multipart/form-data, а человек, проводящий триаж/ревью — вообще забьет на обе сработки, т.к. по логике — копирование файлов тут норм, ведь их исходные пути мы получаем от парсера (ведь только от парсера же, да? 😬), выполняющего здесь ещё и роль доверенного санитайзера.

🖥 Что делать разработчикам?

• Структурные входные данные должны валидироваться по схеме конкретного кейса бизнес-логики, следуя принципу fail-closed, прежде, чем начнется работа с их полями (даже их валидация).

• Не стоит смешивать в одном потоке выполнения несколько логических кейсов. В данном случае — следовало бы разнести по разным эндпоинтам работу с разными типами контента (облегчает задачу SAST, делает счастливыми триажеров и ревьюеров — сплошной профит). Но, если уж смешались, то п.1 должен быть корректно реализован для всех веток выполнения.

• Инварианты и гарантии, предоставляемые используемыми парсерами, валидаторами и санитизаторами стоит изучить досконально. Даже в «нормальной» ветке с multipart/form-data, то, что formidable гарантирует загрузку по безопасным путям относительно options.uploadDir — нужно знать, а не предполагать. А ещё лучше — лишний раз убеждаться в этом, прежде, чем работать с полученными результатами. Почему?

• Потому что, Defense in Depth через многоуровневую модель угроз никто не отменял. То, что, например, через обычную читалку файлов стало возможным вытащить .n8n/database.sqlite говорит о том, что уровней внутренних границ доверия у n8n просто не было.

TL;DR: читаем разбор Ni8mare, делаем выводы, сравниваем с написанным выше ✍️
Please open Telegram to view this post
VIEW IN TELEGRAM
5❤‍🔥2
🔍 Наиболее интересные уязвимости

🐛 CVE-2026-22688, обнаруженная в WeKnora в версиях до 0.2.5, приводит к OS Command Injection. Проблема заключалась в том, что аутентифицированный пользователь мог подставлять значения stdio_config.command/args в MCP stdio-настройки, после чего сервер запускал subprocess с этими значениями, что открывает возможность выполнения произвольных команд на сервере. В исправлении добавили явную валидацию stdio_config (command/args) при создании/обновлении MCP-сервиса: подозрительные/небезопасные значения больше не принимаются и не доходят до запуска процесса.

🐛 CVE-2026-22244, выявленная в OpenMetadata в версиях до 1.11.4, приводит к Server-Side Template Injection (SSTI). Уязвимость обусловлена тем, что злоумышленник с административными правами мог добиться интерпретации опасных конструкций в шаблонах, что в итоге позволяет выполнить код на стороне сервера. В исправлении добавили настройки безопасности для обработчика FreeMarker-шаблонов.

🐛 CVE-2025-68705, обнаруженная в RustFS в версиях с 1.0.0-alpha.13 до 1.0.0-alpha.78, приводит к Path Traversal. Проблема заключалась в том, что имя объекта, приходящее в запросе на эндпоинт /rustfs/rpc/read_file_stream, могло содержать символы обхода пути, из-за чего атакующий мог выйти за пределы ожидаемого каталога и читать произвольные файлы. В исправлении добавили санитизацию путей.

🐛 CVE-2026-22610, выявленная в Angular в версиях до 19.2.18, 20.3.16, 21.0.7 и 21.1.0-rc.0, приводит к Cross-Site Scripting (XSS). Уязвимость обусловлена тем, что внутренняя схема санитизации в компиляторе шаблонов не распознавала href и xlink:href у SVG <script> как контекст Resource URL, из-за чего потенциально опасные URL могли проходить обработку недостаточно строго. В исправлении добавили списки тэгов, которые должны проходить санитизацию

🐛 CVE-2025-68428, обнаруженная в jsPDF в версиях до 4.0.0, приводит к Path Traversal. Проблема заключалась в том, что при контроле аргументов метода loadFile(), можно было передать путь к локальному файлу на диске, и его содержимое попадало в итоговый PDF «как есть», что приводит к чтению произвольных файлов. В исправлении доступ к файловой системе запретили по умолчанию, чтение с диска теперь требует явного разрешения, например, через опцию allowFsRead.
👍3
Первая рабочая неделя в году — самая сложная. Дальше — будет легче (мы узнавали) 🙂

С другой стороны, из этого следует, что правильная половина первой рабочей пятницы в году — самая приятная, разве нет? 🎅
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
9😁7👍2
Трейд-оффы современных языков программирования

Надеюсь, никакой ящик Пандоры я этим постом не открою... 🫣 Для контекста:

Rust неплохой язык, на нём интересно писать… пет-проекты в соло и то, для чего раньше стоило бы взять C/C++. Для наших прототипов и нетребовательного прода — всё ещё Python, для всего остального — Go.


Последнее время плотно занимаюсь оценкой фичей безопасности, которые предлагают те или иные языки программирования и экосистемы. Пост (точнее — статью) об этом попозже обязательно опубликую, а пока захотелось поделиться побочным результатом этого ресерча: сравнением популярных языков в рамках «дешево-быстро-безопасно — выбери любые два».

Для каждого языка сформулировал оценку по 10-бальной шкале, относительно трех критериев разработки:

Совокупная стоимость. Интегральная оценка по всем видам затрат, к которым приводит разработка на этом языке: оптимальная численность и стоимость команд, затраты на тестирование, инфру и поддержку.

Скорость. По сути — временная стоимость стори-поинта в проекте медианной сложности (веб, энтерпрайз, облака).

Безопасность. Уровень безопасности, гарантируемый стандартной поставкой языка и его рантайма.

Проставляя оценки по первым двум критериям, опирался на материалы, наиболее интересные из которых, приведены ниже. Там, где не получалось опираться, давал субъективную оценку, исходя из собственного опыта. Оценку по третьему критерию брал из упомянутого выше ресерча, основанного большей частью на аналитике по спекам и докам языков, и их экосистем, и CVE, которыми страдали написанные на них проекты.

Там, где семейство языков объединено единой экосистемой (.NET, JVM, Node) рассматривал общие для всего семейства свойства, т.к. глубоко убежден, что хотя конкретные языки и могут отличаться друг от друга по заданным критериям, определяющим фактором здесь остается все же их экосистема.

Затем, с помощью полученных оценок, plotly.js и такой-то матери ChatGPT, сделал визуализацию всего этого, скрины которой вы видите выше. Для желающих покрутить 3D-сцену мышкой, скину в комментах HTML.

Примечательно то, что никак не подгоняя изначально данные оценки, и построив по ним на диаграммах Pareto Front (по всем трем критериям), получил ровно три языка, упомянутые в цитате из своих новогодних инсайтов. Pareto Front в данном случае обозначает языки, представляющие все рационально допустимые компромиссы при выборе стека (говоря иными словами — остальные нет смысла учитывать при выборе по этим критериям, т.к. результат будет заведомо хуже).

Разумеется, когда, например, есть готовая и сработавшаяся команда, особенно с уже существующей и стабильной кодовой базой, критерии и способ их подсчета должны быть уже слегка другие. Так что, эти диаграммы скорее о том, на какие языки стоит ориентироваться при старте новых проектов с абсолютного нуля, как минимум.

📰 Материалы, помогавшие делать оценку (заслуживающие внимания):

Top 8 Most Demanded Programming Languages
The 9 cost factors
What Is the Most Secure Coding Language?
2025 Stack Overflow Developer Survey
Which Programming Language Has the Most Vulnerabilities?

TL;DR: в любой непонятной ситуации используйте Python, Go или Rust. В любой понятной — выбирайте язык с умом, под задачу, команду и предметную область. C/C++ не используйте, если можете 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍64👎4🔥2😐1