Перейти до основного вмісту
OpenAI

16 березня 2026 р.

ПродуктЗахист

Чому Codex Security не включає звіт SAST

Протягом десятиліть статичне тестування безпеки застосунків (SAST) було одним із найефективніших способів, за допомогою яких команди безпеки масштабують перевірку коду. 

Але коли ми створювали Codex Security, ми зробили свідомий вибір у проєктуванні: ми не почали з імпорту звіту статичного аналізу й не просили агента виконувати його перегляд. Ми спроєктували систему таким чином, щоб починати з самого репозиторію — його архітектури, меж довіри та передбачуваної поведінки — і перевіряти те, що вона знаходить, перш ніж просити людину витратити на це час. 

Причина проста: найскладніші вразливості зазвичай не є проблемами потоку даних. Вони трапляються, коли код нібито забезпечує перевірку безпеки, але ця перевірка насправді не гарантує властивості, на яку покладається система. Інакше кажучи, складність полягає не лише у відстеженні того, як дані переміщуються в програмі, а й у визначенні того, чи справді засоби захисту в коді працюють.

Проблема: SAST оптимізовано для аналізу потоку даних

SAST часто описують як лінійний процес: визначити джерело ненадійного введення, відстежити дані в програмі та позначити випадки, коли ці дані потрапляють до чутливого приймача без очищення. Це доволі елегантна модель, і вона дійсно охоплює багато реальних помилок.

На практиці ж SAST доводиться робити наближення, щоб залишатися керованим у масштабі, особливо в реальних кодових базах із непрямими зверненнями, динамічною диспетчеризацією, зворотними викликами, рефлексією та складним керуванням потоком виконання, характерним для фреймворків. Ці наближення — не докір SAST; це реальність спроби міркувати про код без його виконання.

Саме це не є причиною, чому Codex Security не починає зі звіту SAST.

Глибша проблема полягає в тому, що відбувається вже після того, як ви успішно простежите шлях від джерела до споживача.

Труднощі статичного аналізу: обмеження та семантика

Навіть коли статичний аналіз коректно простежує вхідні дані через кілька функцій і рівнів, йому все одно потрібно відповісти на запитання, яке фактично визначає, чи існує вразливість:

Чи справді спрацював захист?

Візьмемо поширений шаблон: код викликає щось на кшталт sanitize_html() перед відображенням ненадійного вмісту. Статичний аналізатор може побачити, що очищення відбулося. Зазвичай він не може визначити, чи цього очищення насправді достатньо для конкретного контексту рендерингу, рушія шаблонів, поведінки кодування та подальших трансформацій.

Ось тут і починаються складнощі. Проблема полягає не лише в тому, чи потрапляють дані до кінцевої точки. Ідеться про те, чи перевірки в коді насправді обмежують значення так, як припускає система.

Інакше кажучи, між «код викликає очищення» і «система безпечна» існує велика різниця.

Приклад: валідація перед декодуванням

Ось приклад, який часто зустрічається в реальних системах.

Вебзастосунок отримує JSON-повідомлення, витягує redirect_url, перевіряє його за допомогою regex списку дозволених адрес, URL-декодує його та передає результат обробнику перенаправлення.

Класичний звіт від джерела до кінцевої точки може описати процес так:

ненадійні вхідні дані → перевірка regex → декодування URL → перенаправлення

Але справжнє питання полягає не в тому, чи відбулася перевірка. Ідеться про те, чи ця перевірка справді обмежила значення після наступних перетворень.

Якщо regex запускається до декодування, чи справді він обмежує декодовану URL-адресу так, як її інтерпретує обробник перенаправлення?

Відповідь на це обґрунтовує весь ланцюг перетворень: що дозволяє regex, як працюють декодування та нормалізація, як парсинг URL обробляє крайові випадки та як логіка перенаправлення визначає схеми та авторитети.

Багато вразливостей, які є суттєвими на практиці, виглядають як помилки в порядку виконання операцій, часткова нормалізація, неоднозначності під час аналізу та невідповідності між перевіркою та інтерпретацією. Потік даних видимий. Слабкість полягає в тому, як обмеження поширюються — або не поширюються — через ланцюг перетворень.

Це не просто теоретичний шаблон. У CVE-2024-29041(відкривається у новому вікні) Express був уражений вразливістю відкритого перенаправлення, за якої некоректно сформовані URL-адреси могли обходити поширені реалізації дозволеного списку через те, як цілі перенаправлення кодувалися, а потім інтерпретувалися. Потік даних був простим. Найскладнішим питанням — і тим, що визначало, чи існував баг, — було те, чи залишалася валідація чинною після ланцюжка перетворень.

Наш підхід: спочатку аналіз поведінки, потім перевірка

Codex Security побудований навколо простої мети: зменшити навантаження під час перевірки, виявляючи проблеми на основі більш переконливих доказів. У продукті це означає використання контексту, специфічного для репозиторію (зокрема моделі загроз), а також перевірку важливих проблем із вагомим сигналом в ізольованому середовищі перед їх розглядом. 

Коли Codex Security стикається з межею, що нагадує «валідацію» або «очищення», він не розглядає це як пункт для позначки «виконано» автоматично. Він намагається зрозуміти, що саме код гарантує, а потім намагається спростувати цю гарантію.

На практиці це зазвичай виглядає як комбінація підходів:

  • Читання відповідного шляху коду з повним контекстом репозиторію, як це робив би дослідник безпеки, і пошук невідповідностей між наміром та реалізацією. Це включає коментарі; але модель не вірить коментарям сліпо, тож додавання фрази //Halvar стверджує, що це не баг перед вашим кодом не введе її в оману, якщо баг насправді є.
  • Зведення проблеми до найменшого тестованого фрагмента (наприклад, конвеєра перетворень навколо одного введення) для подальшого її аналізу без впливу решти системи. У цьому сенсі Codex Security виокремлює крихітні фрагменти коду, а потім пише для них мікрофазери.
  • Міркування про обмеження в різних перетвореннях, а не розгляд кожної перевірки окремо. За потреби це може включати формалізацію у вигляді задачі задовільності. Інакше кажучи, ми надаємо моделі доступ до середовища Python із z3-solver, і вона добре вміє користуватися ним за потреби — так само, як це довелося б робити людині, розв'язуючи особливо складну задачу з вхідними обмеженнями. Це особливо корисно для аналізу цілочисельних переповнень або подібних помилок на нестандартних архітектурах.
  • Виконання гіпотез в ізольованому середовищі валідації, де це можливо, щоб відрізнити «це може бути проблемою» від «це проблема». Немає кращого доказу, ніж повний PoC від початку до кінця з кодом, скомпільованим у режимі налагодження. 

Ось де криється головна відмінність: замість того, щоб зупинятися на «перевірку було проведено», система рухається до «інваріант виконується (або ні), і ось докази». І модель обирає найкращий інструмент для цього завдання.

Чому ми не доповнюємо Codex Security звітом SAST

Цілком логічне питання: чому б не об'єднати обидва підходи? Чи можна почати зі звіту SAST, а потім скористатися агентом для глибшого аналізу?

Трапляються випадки, коли попередньо обчислені результати корисні: особливо це актуально для вузьких, відомих класів багів. Але для агента, призначеного для виявлення та перевірки вразливостей у контексті, початок зі звіту SAST створює три передбачувані ризики невдачі перевірки.

По-перше, це може сприяти передчасному звуженню. Список результатів — це карта того, де інструмент уже провів перевірку. Якщо розглядати його як відправну точку, можна змістити систему в бік непропорційних зусиль у тих самих областях, використовуючи ті самі абстракції, і при цьому пропускати цілі класи проблем, які просто не вписуються у світогляд інструмента.

По-друге, це може вводити приховані судження, які буде важко усунути. Багато результатів SAST кодують припущення щодо очищення, валідації або меж довіри. Якщо ці припущення хибні (або просто неповні), внесення їх у цикл міркування може змістити агента від «дослідити» до «підтвердити або відхилити» — а це не те саме, чого ми хочемо від агента.

По-третє, це може ускладнити оцінювання системи міркування. Якщо процес починається з вихідних даних SAST, стає складно відокремити те, що агент виявив завдяки власному аналізу, від того, що він успадкував від іншого інструмента. Це розмежування важливе, якщо ви хочете точно вимірювати можливості системи (а це потрібно для вдосконалення системи в майбутньому).

Тож за нашою задумкою Codex Security починає там, де починаються дослідження безпеки: із коду та наміру системи, проводячи перевірку для підвищення рівня впевненості перед тим, як звертатися до людини.

Інструменти SAST усе ще дуже важливі

Інструменти SAST показують чудові результати в тому, для чого їх було створено: забезпеченні дотримання стандартів безпечного кодування, виявленні очевидних проблем «від джерела до кінцевої точки» та виявленні відомих патернів у великому масштабі з передбачуваними компромісами. Вони можуть бути важливою складовою глибинної безпеки.

Ідея цієї статті дещо вужча: вона пояснює, чому агент, створений для аналізу поведінки та перевірки висновків, не повинен починати свою роботу з прив'язки до статичного списку висновків.

Варто також зазначити пов’язане обмеження суто підходу «від джерела до кінцевої точки»: не кожна вразливість є проблемою потоку даних. У реальності багато збоїв є проблемами стану та інваріантів: обходи робочих процесів, прогалини в авторизації та баги типу «система перебуває в неправильному стані». Для таких типів багів скомпрометоване значення не потрапляє до жодної «небезпечної кінцевої точки». Ризик полягає в тому, що програма припускає, що завжди буде правдою. 

Наші перспективи

Ми очікуємо, що екосистема інструментів безпеки й надалі вдосконалюватиметься: статичний аналіз, фазинг, захисні механізми під час виконання та робочі процеси з агентами — усе це матиме свою роль.

Ми хочемо, щоб Codex Security добре справлявся з тією частиною роботи, яка вартує командам безпеки найбільше: перетворення «це виглядає підозріло» на «це справді так, ось як це призводить до помилки, і ось виправлення, яке відповідає задуму системи». 

Якщо ви хочете дізнатися більше про те, як Codex Security сканує репозиторії, перевіряє результати та пропонує виправлення, перегляньте нашу документацію(відкривається у новому вікні).

Автор

OpenAI