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

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

ШарЩо він робить
Секретне скануванняЗнаходить витік облікових даних у сховище та його історію.
Фільтрація краївWAF перед програмою, фільтрує явно шкідливий трафік.
Захист від ботівCAPTCHA або виявлення ботів на основі балів у формах, які мають залишатися загальнодоступними.

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

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

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

Більшість із цих рівнів мають надійну самостійну опцію, яка працює на будь-якому хості — gitleaks для секретів, ModSecurity для WAF, OSV-Scanner для залежностей, Semgrep для SAST, ZAP для DAST. Вони залишаються основними протягом усього часу. Для еквівалентів керованої хмари, де ви обмінюєте частину роботи з налаштування на налаштований постачальником набір правил і інформацію про загрози, кожна велика хмара постачає свою власну. Ми звернемося до Google Cloud Platform як конкретного посилання, коли керований приклад допоможе: Cloud Armor для WAF, Аналіз артефактів для сканування контейнерів, reCAPTCHA Enterprise і Адаптивний захист для захисту від ботів. Вибір однієї хмари зберігає ці приклади конкретними, а не помахом рукою; AWS, Azure та Cloudflare пропонують еквіваленти, про які ми коротко згадаємо, але не будемо детально занурюватися.

Три категорії невідомих

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

Що міститься в коді та репозиторії. Ви не знаєте, які маршрути існують — застарілі програми ростуть органічно, і, ймовірно, є кінцеві точки адміністратора, про які ніхто не згадував. Ви не знаєте, що насправді робить код, або тому, що ви не можете прочитати його досить швидко (застарілий), або тому, що ніхто не прочитав його уважно (згенерований ШІ). І ви не знаєте, що вже просочилося в історію git. DAST досліджує запущену програму ззовні, щоб визначити, що насправді відкрито; SAST дає вам втрачену, але корисну карту ризикованих шаблонів коду; секретне сканування виявляє облікові дані, забуті в старих комітах.

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

Виробничий трафік. Журнали запитів і WAF можуть виявити спостережувані моделі атак і помилкові спрацьовування. Вони забезпечують часткову видимість, а не повну інформацію про зловмисників або доказ того, що непозначений трафік є безпечним.

Жоден інструмент не вирішить усіх цих проблем. Кожен із трьох наведених нижче рівнів стосується одного або кількох із них; сканування залежностей (розглянуте після шарів) і SAST/DAST (наприкінці) розширюють глибину, коли основи вже на місці.

Секретне сканування

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

Проскануйте відповідну історію сховища, вивчіть знахідки та відкликайте або змініть справжні розкриті облікові дані. Додайте перевірки майбутніх змін у CI.

Інструменти

  • gitleaks — швидкі, засновані на Go, чудові правила за замовчуванням, що охоплюють більшість постачальників (AWS, GCP, Azure, Stripe, Twilio, токени GitHub, приватні ключі, JWT). Перевірте всю історію, а не лише HEAD.
  • трюфель — аналогічне виявлення, але додає крок перевірки: воно перевіряє, чи виявлений секрет дійсно активний (наприклад, робить виклик sts:GetCallerIdentity для ключів AWS). Високий вихід сигналу, вартий додаткової затримки.
  • git-секрети — орієнтований на AWS, легкий, корисний як хук перед фіксацією.
  • Секретне сканування GitHub — безкоштовно для публічних сховищ, розширена безпека для приватних. Партнери-постачальники можуть відкликати виявлені токени; підтверджувати відкликання, а не припускати його.

Запуск сканування та читання результату

gitleaks можна встановити декількома способами — попередньо зібраний двійковий файл, Homebrew, go install або через Docker. Ми використаємо Docker тут для зручності: нічого не потрібно встановлювати на хості, та сама команда працює на будь-якій машині з демоном Docker, а програми CI отримують той самий виклик, що й ваш ноутбук.

Я щойно перевірив це на репо, у якому знаходиться ця стаття:

docker run --rm -v "$(pwd):/repo" zricethezav/gitleaks:latest \
    git /repo --log-opts="--all" --redact --verbose

--log-opts="--all" проходить кожен комміт на кожній гілці, а не лише HEAD; --redact маскує секретне значення у виводі, тому сам звіт не є новим витоком; --verbose друкує повний блок пошуку замість просто підсумкової кількості.

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

Finding:     STRIPE_SECRET_KEY=REDACTED
Secret:      REDACTED
RuleID:      stripe-access-token
Entropy:     4.175736
File:        blog/src/content/blog/anatomy-of-a-developer-targeted-supply-chain-attack.mdx
Line:        225
Commit:      49e4ca23a5ee6d1ef6b1a566a580a4086fbb84aa
Fingerprint: 49e4ca23a5ee6d1ef6b1a566a580a4086fbb84aa:blog/src/content/blog/anatomy-of-a-developer-targeted-supply-chain-attack.mdx:stripe-access-token:225

П’ять важливих полів:

ПолеЩо це вам говорить
RuleIDЯке правило виявлення спрацювало (stripe-access-token, aws-access-token, generic-api-key, private-key тощо). Повний набір правил за замовчуванням міститься в config/gitleaks.toml у репозиторії gitleaks — кожне правило з регулярним виразом, описом і будь-якими фільтрами ключових слів.
Файл + рядокДе сірник.
ЗдійснитиЯкий коміт його представив — не обов’язково останній. gitleaks знаходить його всюди, де воно вперше з’являється в історії.
ЕнтропіяЕнтропія Шеннона відповідного рядка, у бітах на символ. Вищий = більш випадковий на вигляд, що зазвичай означає більшу ймовірність бути справжнім секретом. Правила загального ключа API використовують ентропію як основний сигнал; правила провайдера (Stripe, AWS) відповідають префіксу і не потребують його.
Відбиток пальцяСтабільний ідентифікатор, який ви використовуватимете для придушення цього висновку, якщо він виявиться прийнятним. Детальніше про це нижче.

Що насправді вимірює ентропія

Частотно-символьна ентропія, яка використовується в таємному скануванні, становить −Σ p(c) log₂ p(c). Його максимум становить log₂(N) для N однаково частих символів. Він ігнорує порядок символів, тому передбачувана послідовність може отримати високу оцінку; це не доводить криптографічну випадковість.

Ентропія — це евристика, яка використовується разом із шаблонами та контекстом. Hex має теоретичну межу в 4 біти на символ, 62-символьний буквено-цифровий алфавіт — приблизно 5,95, а 64-символьний алфавіт Base64 — 6. Короткі зразки часто опускаються нижче цих стель.

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

Результати сортування

Коли ви фактично запускаєте gitleaks проти реального репо, ви отримуєте три категорії знахідок — і одна відповідь не підходить для всіх трьох:

  1. Справжні облікові дані: анулюйте або змініть їх, перевірте ризики та видаліть їх з активних файлів. Переписування історії може зменшити подальший ризик, але не скасовує витік ключа.
  2. Навмисний приклад: переконайтеся, що значення є несекретним заповнювачем або схваленим, відкликаним зразком, перш ніж його приховувати. Цитування в статті про безпеку не є доказом нешкідливості.
  3. Помилковий результат: записує, чому збіг не є секретом, і приховує цей конкретний висновок.

Для категорій 2 і 3 виправлення — це файл .gitleaksignore у кореневому каталозі сховища, який містить ідентифікатори — поле Fingerprint із таблиці вище — результатів, які ви переглянули та схвалили:

# Intentional: secrets quoted as evidence in supply-chain writeup
49e4ca23a5ee6d1ef6b1a566a580a4086fbb84aa:blog/src/content/blog/anatomy-of-a-developer-targeted-supply-chain-attack.mdx:stripe-access-token:225
49e4ca23a5ee6d1ef6b1a566a580a4086fbb84aa:blog/src/content/blog/anatomy-of-a-developer-targeted-supply-chain-attack.mdx:generic-api-key:193

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

Зупиніть наступний витік під час фіксації

Після того, як історичне сканування буде чистим (або з відбитками пальців і придушеним), дріт просочиться до:

  • CI: сканує коміти перед об’єднанням і публікацією.
  • Хуки перед фіксацією: перевіряйте поетапні зміни перед створенням коміту. Ці перевірки зменшують випадкові витоки, але можуть пропустити непідтримувані шаблони або їх обійти.

Фільтрація по краях за допомогою WAF

Брандмауер веб-додатків перевіряє запити HTTP(S) на відповідність набору правил. Він вирішує дозволити, зареєструвати, заблокувати або оскаржити кожен запит, перш ніж він досягне вашої програми. WAF корисний для:

  • Перехоплення очевидних корисних навантажень для класів атак: впровадження SQL, XSS, локальне/віддалене включення файлів, впровадження команд, обхід шляху.
  • Блокування відомих шкідливих шляхів (/wp-admin/, .git/config, .env).
  • Обмеження швидкості, блокування репутації IP, геофільтрація.
  • Купуючи час, коли CVE падає в залежності, яку ви не можете оновити сьогодні.

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

Керовані та самостійно розміщені WAF відрізняються механізмами, правилами, обмеженнями та функціями роботи. Звичайний власний стек використовує ModSecurity із Основним набором правил OWASP. CRS може комбінувати відповідні правила за допомогою підрахунку аномалій; керовані продукти можуть використовувати CRS-похідні та власні виявлення.

Керується: Cloud Armor

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

Власний параметр GCP – Google Cloud Armor. Він підключається до балансувальника навантаження GCP HTTP(S), а його попередньо налаштовані групи правил (sqli-v33-stable, xss-v33-stable, lfi-v33-stable, rce-v33-stable тощо) отримують безпосередньо з OWASP CRS — того самого набору правил, який ви встановлюєте вручну за допомогою ModSecurity.

Ви можете налаштувати Cloud Armor за допомогою консолі GCP, gcloud CLI, REST API або, як ми покажемо нижче, декларативно в Terraform. Модель однакова незалежно від інтерфейсу: політика безпеки Cloud Armor — це список правил із умовами відповідності та діями (allow, deny(403), rate_based_ban). Мінімальна політика, яка вмикає попередньо налаштовані групи правил CRS і розумну дію за умовчанням, виглядає так:

resource "google_compute_security_policy" "app" {
  name = "app-waf"

  rule {
    action   = "deny(403)"
    preview  = true
    priority = 1000
    match {
      expr { expression = "evaluatePreconfiguredWaf('sqli-v33-stable', {'sensitivity': 2})" }
    }
    description = "Block SQL injection"
  }

  rule {
    action   = "deny(403)"
    preview  = true
    priority = 1001
    match {
      expr { expression = "evaluatePreconfiguredWaf('xss-v33-stable', {'sensitivity': 2})" }
    }
    description = "Block XSS"
  }

  rule {
    action   = "allow"
    priority = 2147483647
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
    description = "Default allow"
  }
}

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

Спеціальні правила Cloud Armor використовують підмножину CEL, тому правила ModSecurity SecRule потрібно перекладати, а не копіювати. Ви можете вибрати версії CRS, які підтримує Google, але не можете завантажити довільний вихідний випуск. Враховуйте витрати на політику та запити, а також витрати на балансування навантаження.

Інші керовані параметри включають AWS WAF, Azure WAF і Cloudflare WAF. Їх точки розгортання, набори правил і елементи керування попереднім переглядом або журналюванням відрізняються.

Самостійне розміщення: ModSecurity + NGINX

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

Конектор NGINX завантажується як динамічний модуль і підключає NGINX до libmodsecurity, яка оцінює налаштовані правила. Архітектура - це:

Internet  →  NGINX + ModSecurity  →  upstream app

Ось як розташовані три частини:

  • NGINX є зворотним проксі. Він припиняє роботу TLS, приймає вхідні HTTP-запити та — коли їх ніщо не блокує — надсилає їх проксі-сервер до додатка, що працює вище, через приватний порт.
  • libmodsecurity — це механізм оцінювання правил. Це бібліотека C++, відокремлена від самої NGINX, без власного мережевого коду — вона просто приймає запит як вхідні дані та повертає вердикт.
  • З’єднувач NGINX ModSecurity — це динамічний модуль (файл .so), який поєднує ці два. Він підключається до конвеєра обробки запитів NGINX і для кожного вхідного запиту передає URL-адресу, заголовки та тіло libmodsecurity для оцінки.

Усі три елементи працюють в одному процесі NGINX. Механізмом є завантажувач динамічних модулів NGINX — і конектор, і libmodsecurity завантажуються в кожен робочий процес NGINX під час запуску, без окремого демона ModSecurity, без IPC, без сокета між ними.

Конектор викликає libmodsecurity в кожному робочому процесі NGINX. Це дозволяє уникнути додаткового стрибка мережі, але оцінка правил все одно додає роботи. Створіть конектор для використовуваної версії та конфігурації модуля NGINX.

Для кожного запиту NGINX передає URL-адресу, заголовки та тіло в libmodsecurity (через конектор). libmodsecurity запускає їх через завантажені правила — CRS OWASP плюс будь-які спеціальні — накопичує оцінку аномалії та повертає дію: allow, log або deny. Якщо вердикт deny, NGINX повертає налаштовану відповідь про помилку (зазвичай 403) і ніколи не пересилає на вихідний канал. В іншому випадку запит виконується нормально.

Коли WAF встановлено, переконайтеся, що все це вірно:

  • Обмежте доступ до програми, щоб запити проходили через WAF; загальнодоступне походження дозволяє зловмисникам обійти його.
  • TLS завершується на WAF. ModSecurity не може перевірити те, що не може розшифрувати.
  • WAF тепер є єдиною точкою відмови — запустіть принаймні два екземпляри за LB, якщо час безвідмовної роботи має значення.
  • Обсяг журналу аудиту різко зросте. План зберігання.

Встановити форму на Debian/Ubuntu (скорочено):

# libmodsecurity
git clone --depth 1 -b v3/master https://github.com/owasp-modsecurity/ModSecurity
cd ModSecurity && git submodule init && git submodule update
./build.sh && ./configure && make -j$(nproc) && make install

# NGINX connector module (must match your NGINX version)
git clone --depth 1 https://github.com/owasp-modsecurity/ModSecurity-nginx
cd nginx-${NGINX_VERSION}
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
make modules && cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/

# OWASP Core Rule Set
git clone --depth 1 https://github.com/coreruleset/coreruleset /etc/nginx/modsec/crs
cp /etc/nginx/modsec/crs/crs-setup.conf.example /etc/nginx/modsec/crs/crs-setup.conf

Потім у nginx.conf:

load_module modules/ngx_http_modsecurity_module.so;

http {
    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsec/main.conf;

    server {
        listen 443 ssl;
        server_name legacy-app.example.com;
        ssl_certificate     /etc/ssl/certs/app.crt;
        ssl_certificate_key /etc/ssl/private/app.key;

        location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

Спочатку розгортайте режим лише виявлення. Встановіть SecRuleEngine DetectionOnly принаймні на тиждень. Прочитайте журнал аудиту. Ви шукаєте хибні спрацьовування (правила CRS спрацьовують щодо законного трафіку — редактори, інформаційні панелі адміністратора, завантаження файлів) і несподівані справжні спрацьовування (атаки вже вражають вас). CRS використовує оцінку аномалій — правила вносять оцінку, і запит блокується лише тоді, коли загальна сума перетинає порогове значення — що робить налаштування м’якшим, ніж блокування за правилом.

Коли ви виявите помилковий результат, спершу використовуйте SecRuleRemoveById для конкретного місця, потім знизите рівень параної на шляху та вимкніть правило глобально лише в крайньому випадку. Переверніть SecRuleEngine On лише після того, як журнали стануть достатньо тихими, щоб мати сенс.

Для віртуального патча на /api/report?format=X це правило фази 1 відхиляє значення format рядка запиту поза дозволеним списком. Він не вимагає наявності параметра або перевірки параметра тіла запиту:

SecRule REQUEST_URI "@beginsWith /api/report" \
    "id:1000001,phase:1,chain,deny,status:400,\
     msg:'virtual patch: /api/report format allowlist'"
    SecRule ARGS:format "!@rx ^(pdf|csv|json)$"

Захист від ботів і CAPTCHA

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

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

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

Інтеграція веб-переглядача створює маркери, які потрібно перевірити на сервері або на межі. Детектори мережевого рівня використовують інші сигнали; деякі продукти для керування ботами також поєднують їх із клієнтським JavaScript.

Ми почнемо з найпростішого в налаштуванні — Cloudflare Turnstile — потім розглянемо глибшу власну комбінацію GCP reCAPTCHA Enterprise і Cloud Armor Adaptive Protection для команд, яким потрібно більше.

Турнікет Cloudflare (найпростіший шлях)

Cloudflare Turnstile надає тести для веб-переглядача та маркер, перевірений через API Siteverify. Керований режим може показувати взаємодію за потреби; він не завжди невидимий і не розкриває оцінку ризику в стилі reCAPTCHA. Міграція з reCAPTCHA вимагає змін інтеграції клієнта та сервера.

Турнікет можна використовувати без перенесення хостингу сайту або DNS на Cloudflare. Дотримуйтесь документації з налаштування як для віджета, так і для перевірки на сервері.

Turnkitele перестає бути достатнім, коли вам потрібен точніший контроль — оцінки кожного запиту, на які ви можете діяти (а не просто пройдено/не пройдено), застосування в балансирі навантаження, а не в коді програми, або правила, більш тонкі, ніж «завдання пройдено/не пройдено». Саме цю прогалину заповнює наведена нижче комбінація reCAPTCHA Enterprise + Cloud Armor.

reCAPTCHA Enterprise (поглиблена інтеграція GCP)

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

Cloud Armor може оцінювати підтримувані токени reCAPTCHA у виразах політики безпеки. Перевірте дійсність жетона, а також оцінку; відсутні або недійсні маркери потребують чіткої політики.

rule {
  action   = "deny(403)"
  priority = 500
  match {
    expr {
      expression = "token.recaptcha_action_token.valid && token.recaptcha_action_token.score < 0.5"
    }
  }
  description = "Block low-score bot traffic to sensitive endpoints"
}

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

У Cloud Armor також є належний WAF-режим, який називається діями керування ботом (redirect, googleRecaptcha), який запускає виклик reCAPTCHA, вбудований на краю — корисний для сценарію «підозрілий сплеск трафіку, кидайте виклик усім, поки він не вщухне».

Виявлення лише за допомогою класифікатора (без інтеграції на стороні клієнта)

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

Адаптивний захист Cloud Armor зосереджується на виявленні DDoS на рівні 7 і пропонує правила пом’якшення. Cloudflare Bot Management надає сигнали виявлення ботів за допомогою кількох методів виявлення. Вони вирішують проблеми, що збігаються, але не є еквівалентними класифікаторами для кожного запиту.

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

  • Застосовуйте елементи керування до таких дій, які можуть призвести до зловживань, як-от реєстрація, вхід і скидання пароля.
  • Перевіряйте контрольні маркери на стороні сервера та явно обробляйте відсутні або недійсні маркери.
  • Поєднайте їх із обмеженнями швидкості та моніторингом.
  • Захист адміністративного доступу за допомогою автентифікації та авторизації; додайте мережеві обмеження, де це необхідно.

За межами — сканування залежностей за допомогою OSV-Scanner

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

Чому OSV-Scanner

OSV-Scanner перевіряє версії залежностей за базою даних уразливостей OSV, яка об’єднує рекомендації з кількох екосистем, зокрема GitHub Security Advisories. Джерела консультацій і охоплення пакетів залежать від сканерів.

Він зчитує загальні файли блокувань (package-lock.json, yarn.lock, Pipfile.lock тощо), вирішує кожен пакет у його точній закріпленій версії та повідомляє про вразливості з ідентифікаторами CVE, серйозністю та (якщо є у OSV) діапазоном версій, який їх виправляє.

Запуск сканування та читання результату

OSV-Scanner можна встановити через Go, Homebrew, попередньо зібраний двійковий файл або — як і gitleaks вище — запустити через Docker. Ми покажемо Docker для узгодженості.

Я щойно перевірив це на репо, у якому знаходиться ця стаття:

docker run --rm -v "$(pwd):/src" ghcr.io/google/osv-scanner:latest \
    scan source --recursive /src

--recursive переглядає кожен каталог під /src і знаходить файли блокувань у вкладених проектах (блог, кілька демонстрацій, сервер, чернетки експериментів). Без нього сканер перевіряє лише верхній рівень — добре для однопроектного репо, але більшість справжніх мають файли блокування, розподілені по кількох каталогах.

Підсумок в кінці прогону виглядає так:

Total 35 packages affected by 59 known vulnerabilities (2 Critical, 17 High, 37 Medium, 3 Low, 0 Unknown) from 2 ecosystems.
59 vulnerabilities can be fixed.

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

URL-адреса OSVCVSSЕкосистемаПакетВерсіяВиправлена версіяДжерело
GHSA-xq3m-2v4x-88gg9.4npmprotobufjs7.5.47.5.5blog/…/transformers-js-demo/package-lock.json
GHSA-p9ff-h696-f5838.2npmвіт7.3.17.3.2blog/package-lock.json
PYSEC-2025-407.5PyPIтрансформатори4.48.34.49.0blog/…/from-scratch/requirements.txt
GHSA-r5fr-rjxr-66jc8.1npmлодаш4.17.234.18.0server/package-lock.json
  • OSV URL — пряме посилання на консультацію на osv.dev (ідентифікатор CVE, вектор атаки, діапазон уражених версій, посилання).
  • CVSS — оцінка тяжкості за 0–10-бальною шкалою. 9+ — критичний, 7–8,9 — високий, 4–6,9 — середній.
  • Ecosystem — з якого реєстру пакунків походить залежність. Одне ім’я пакета може існувати в кількох екосистемах і отримувати різні CVE.
  • Package і Version — те, що зараз закріплено у файлі блокування.
  • Fixed version — найнижча версія, яка вирішує проблему. Часто оновлення патчів; іноді другорядний або великий.
  • Source — з якого файлу блокування отримано знахідку. Критично для monorepos: той самий пакет можна закріпити в різних версіях у різних підпроектах, що саме ми бачимо для vite, protobufjs і picomatch під час фактичного сканування.

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

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

OSV-Scanner також підтримує робочі процеси файлів блокування, SBOM і зображень. Використовуйте документацію для синтаксису команд встановленої версії та вимог до доступу до контейнера.

Що робити з висновками

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

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

Виявлення без придатного виправлення потребують пом’якшення та постійного відстеження:

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

Альтернативи та коли вибрати кожну з них

Інші параметри включають Artifact Analysis для підтримуваних образів реєстру, Trivy для кількох типів артефактів і конфігурацій і Dependabot для сповіщень і запитів на оновлення. Увімкніть потрібні функції та перевірте охоплення їх екосистеми; вони не є взаємозамінними скануваннями тих самих даних.

Розумний мінімальний стек: OSV-Scanner в CI (закриває збірку на основі нових знахідок високого рівня серйозності) + Dependabot (постійно відкриває PR оновлення). Якщо ви вже відправляєте контейнери, або додайте Trivy для сканування зображень, або — якщо ви натискаєте на хмарний реєстр — покладіться на вбудований сканер реєстру (Artifact Analysis на GCP, ECR + Inspector на AWS), а не використовуйте інший інструмент.

Сканери не є гігієною ланцюга постачання

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

OWASP Шпаргалка безпеки NPM — це корисний конкретний контрольний список для цього, якщо ваш стек Node.js — охоплює --ignore-scripts, npm audit, пакети з областю дії, typosquat-spotting тощо. Шпаргалка щодо керування вразливими залежностями OWASP охоплює ту саму мову агностику. Обидва добре поєднуються з наведеним вище шаром на основі сканера: сканери для завідомо-поганих, гігієна для невідомих-поганих.

Що покриває цей стек і що може піти далі

Якщо ви розгортаєте три основні рівні та сканування залежностей, що ви насправді купили собі?

Що можуть зменшити ці елементи керування: розкриті секрети, використання відомих залежностей після виправлення, відповідні зловмисні запити та деякі автоматизовані порушення. Покриття залежить від конфігурації, меж виявлення та подальшої обробки результатів.

Ще пропустив:

  • Вразливі шаблони у вашому власному коді. WAF блокує корисні дані під час запиту, але не допомагає вам знайти або виправити базовий вразливий код. SAST і DAST нижче вказують, як ви починаєте.
  • Недоліки в логіці програми — все, що вимагає знання того, що має робити програма. IDOR (запит до /orders/1234, коли користувач має бачити лише 1233), несправна автентифікація чи керування сеансом, відсутні або непослідовні перевірки авторизації, помилки бізнес-логіки, як-от пропуск кроку оплати шляхом повторного відтворення запиту на оформлення кошика. Жоден із них не виглядає шкідливим для сканера.
  • Нові нульові дні в додатку або його залежностях до появи підписів.
  • Рішучі вороги. Інсайдери зловживають законним доступом. Добре забезпечені оператори-боти, які оплачують послуги визначення CAPTCHA та обертають IP-адреси швидше, ніж ви можете їх заблокувати.

Що додати далі: SAST і DAST

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

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

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

Перегляд зображення

Змінюйте масштаб жестом щипка або клавішами + / −. Переміщуйте зображення перетягуванням або стрілками. Esc — закрити.