Виявлена вразливість у задеплоєній програмі Solana — це інцидент, що вимагає чіткої послідовності дій: від класифікації загрози до патчу й аналізу причин. Нижче — покрокова інженерна інструкція, орієнтована на команди, які вже мають задеплоєний програмний код у mainnet-beta і виявили або отримали повідомлення про вразливість.

Увага: цей матеріал містить загальні інженерні рекомендації щодо реагування на інциденти безпеки. Конкретні кроки для вашого проєкту обовʼязково мають бути узгоджені з профільним security-аудитором після аналізу фактичного коду та стану мережі.

Оцінка критичності та пріоритет

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

Критерії оцінки

Оцінюйте за трьома вимірами:

  • Експлуатованість. Чи може атакувальник скористатися вразливістю без спеціальних умов? Чи потрібен попередній стан акаунта, специфічна послідовність транзакцій або доступ до приватних ключів?
  • Вплив на кошти. Чи можливе пряме виведення SOL або токенів з PDA-акаунтів? Чи можна маніпулювати балансами чи авторизаціями?
  • Вплив на стан. Чи порушується цілісність даних програми? Чи можна перевести програму в стан, з якого неможливо відновити коректну роботу навіть після патчу?

Матриця пріоритету

Рівень Ознаки Час реакції
Критичний Пряме виведення коштів із PDA без затвердження власником; знищення стану програми Негайно (хвилини)
Високий Експлуатація можлива за наявних умов у mainnet; непрямий вплив на кошти через CPI-ланцюги Від 1 до 4 годин
Середній Потенційна проблема, що потребує специфічного стану або послідовності дій, який наразі відсутній у mainnet Від 24 до 72 годин
Низький Теоретична вразливість без реальних векторів експлуатації в поточній конфігурації У межах регулярного циклу релізу

Типова помилка

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

Екстрене оновлення програми

На Solana програми за замовчуванням є незмінними після розгортання. Оновлення можливе лише за наявності upgrade authority — облікового запису з правом перезапису байткоду програми. Якщо ви втратили доступ до upgrade authority або відмовилися від нього (close authority), екстрене оновлення неможливе — це окремий клас інцидентів, що виходить за межі цього матеріалу.

Передумови

  • Доступ до ключа upgrade authority (або multisig, що його контролює)
  • Зібраний патчений бінарник (.so файл) програми
  • Доступ до RPC-вузла mainnet-beta з можливістю відправки транзакцій
  • CLI Solana (solana-cli) версії, сумісної з поточним cluster version мережі — перевірте актуальну версію в офіційному репозиторії
  • Тестове середовище devnet із розгорнутою копією програми для попередньої перевірки

Крок 1. Підготовка патчу та локальна перевірка

Застосуйте мінімально необхідні зміни до коду. Не змішуйте патч безпеки з рефакторингом або новим функціоналом — це ускладнює перевірку та збільшує ризик побічних ефектів.

Запустіть повний набір тестів локально. Очікуваний результат: усі тести проходять, нові тести для конкретної вразливості підтверджують її усунення.

Крок 2. Перевірка на devnet

Задеплойте патчену версію на devnet і перевірте:

  • Коректність усунення вразливості на тестових даних, що відтворюють вектор атаки
  • Збереження зворотної сумісності: існуючі інструкції та облікові записи продовжують працювати
  • CPI-виклики з інших програм не ламаються (зміна порядку аргументів або типів даних у інструкціях — поширена причина таких збоїв)

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

Крок 3. розгортання у mainnet-beta

Виконайте оновлення через solana program deploy з прапорцем --upgrade-authority. Якщо upgrade authority контролюється multisig, ініціюйте відповідну транзакцію з урахуванням кворуму.

Ризики:

  • Транзакція оновлення може не встигнути обробитися, якщо мережа переживає підвищене навантаження — плануйте запас часу
  • Якщо між devnet-тестуванням і mainnet-деплоєм хтось змінив стан програми (наприклад, закрив важливий PDA), патч може виявитися некоректним для нового стану

Крок 4. Верифікація після оновлення

Після підтвердження транзакції оновлення перевірте:

  • Програмний ID збігається з очікуваним
  • Хеш байткоду відповідає патченій версії (через solana program show)
  • Тестова транзакція, що відтворювала вектор атаки, тепер відхиляється з очікуваною помилкою
  • Регулярні користувацькі транзакції обробляються коректно

План відкату

Solana не підтримує пряме пониження версії програми (downgrade). Відкат можливий лише шляхом розгортання попередньо відомої коректної версії байткоду поверх поточної. Тому:

  • Зберігайте байткод останньої стабільної версії перед кожним оновленням
  • Якщо патч виявився некоректним, деплойте збережену стабільну версію тим самим механізмом оновлення
  • Якщо використовується патерн програми-проксі (proxy pattern), відкат може полягати у перемиканні на попередню версію — це швидше, але вимагає, щоб архітектура була спроєктована заздалегідь

Комунікація зі спільнотою

Комунікація — не додаток до технічної реакції, а її складова частина. Неправильна комунікація здатна посилити наслідки інциденту навіть за успішного патчу.

Якщо вразливість ще не експлуатується

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

Якщо вразливість вже експлуатується

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

Канали та формат

Вибір каналів залежить від масштабу:

  • Внутрішні канали команди — негайно, для координації реагування
  • Офіційний Discord проєкту — для оперативного інформування активної спільноти
  • Офіційний X (Twitter) — для широкого повідомлення, якщо інцидент публічний
  • Постінцидентний звіт — детальний технічний розбір після завершення реакції (через 24–72 години після закриття інциденту)

Типова помилка

Мовчання «до вирішення». Навіть повідомлення «Ми виявили проблему, працюємо над виправленням, детальніше повідомимо пізніше» краще за відсутність будь-якої комунікації. У спільноті Solana інформація поширюється швидко, і відсутність офіційної позиції заповнюється припущеннями.

Постінцидентні зміни в процесах

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

Root cause analysis

Визначте фактичну причину появи вразливості, а не її симптом. Типові причини на Solana:

  • Відсутність перевірки signer у інструкціях, що змінюють стан PDA — атакувальник передає свій ключ як signer, і програма приймає транзакцію
  • Некоректна перевірка PDA — використання seeds, що залежать від неконтрольованого вводу, що дозволяє похідну іншого PDA
  • Відсутність перевірки балансу після обчислень — overflow/underflow у розрахунках токенних сум
  • Довіра до даних із CPI без додаткової валідації — програма-клієнт передає дані, які не перевіряються на стороні програми-виконавця

Для кожної причини зафіксуйте: де саме в процесі розробки або ревʼю вона не була виявлена.

Зміни в CI/CD

Впровадьте або посильте автоматизовані перевірки, що могли б виявити цей клас проблем:

  • Статичний аналіз коду (cargo clippy з суворими налаштуваннями, спеціалізовані linters для Anchor-програм)
  • Обовʼязкові тести на граничні значення (edge cases) для фінансових обчислень
  • Перевірка наявності перевірки signer у всіх інструкціях, що модифікують стан
  • Блокування мержу до mainnet-гілки без проходження повного тестового циклу

Зміни в процесі ревʼю

  • Додайте чек-лист ревʼю безпеки до pull request-процесу (не як формальність, а як обовʼязковий крок з іменним підтвердженням ревʼюєра)
  • Визначте мінімальний рівень досвіду ревʼюєра для коду, що працює з коштами або критичним станом
  • Якщо інцидент стався після зовнішнього аудиту, проаналізуйте, чому аудит його не виявив: обмеження scope, недостатня глибина, зміни коду після аудиту

Моніторинг та алертинг

Додайте метрики й алерти, що дозволили б виявити експлуатацію цієї вразливості раніше:

  • Моніторинг аномальних паттернів транзакцій (наприклад, незвична кількість викликів конкретної інструкції за короткий проміжок часу)
  • Алерти на зміну балансів критичних PDA-акаунтів
  • Логування невдалих транзакцій з конкретними помилками, що можуть вказувати на спроби експлуатації

Документування

Створіть внутрішній постінцидентний звіт, що містить:

  • Хронологію інциденту з точними часовими мітками
  • Фактичну причину та вектор експлуатації
  • Опис патчу та результати перевірки
  • Що спрацювало добре, а що — ні
  • Конкретні зміни в процесах із іменними відповідальними та дедлайнами впровадження

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

Джерела