Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Новини 18 вересня 2026

Laravel Scalpel: Сканер для виявлення слідів вторгнень у файлову систему

Laravel Scalpel - це сканер слідів вторгнень від Harry Agustiana, який працює всередині Laravel-додатка та перевіряє файлову систему на ознаки компрометації: підозрілі PHP-файли, обфускований код, змінені серверні директиви та зміни порівняно з еталонним знімком.

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

Сканери файлової системи

Команда scalpel:scan за замовчуванням запускає шість сканерів. П'ять з них перевіряють поточні файли, а Baseline Diff scanner порівнює їх зі збереженим знімком.

Структурний сканер шукає виконувані PHP-файли в директоріях, де PHP не повинно бути. За замовчуванням це public/ та storage/. Він виявляє .php файли та менш поширені розширення, такі як .phtml, .pht і .phar, а також подвійні розширення на кшталт shell.php.jpg. Сканер дозволяє public/index.php, public/vendor/ та скомпільовані views і cache Laravel за замовчуванням. Ви можете змінити скановані директорії та додати власні файли й папки до списків дозволених.

Сканер обфускованого коду перевіряє PHP-файли на типові паттерни бекдорів. Серед них: eval(base64_decode(...)), виконання стиснутого payload, динамічні виклики функцій, пряме виконання вхідних даних запиту та довгі закодовані рядки. Якщо легітимний код викликає спрацювання, ви можете вимкнути відповідний паттерн у config/scalpel.php.

Сканер .htaccess повідомляє про handler та MIME type mappings, які дозволяють веб-серверу виконувати Python, Perl, CGI або інші скрипти. Він також позначає Options +ExecCGI, rewrite rules, що перенаправляють на зовнішні URL, та PHP-директиви на кшталт auto_prepend_file.

Сканер .user.ini повідомляє про PHP-директиви для конкретних директорій, включно з auto_prepend_file, auto_append_file, include_path та disable_functions. Зловмисник може використати auto_prepend_file для запуску прихованого файлу при кожному запиті.

Сканер environment повідомляє про .env файл, який відсутній, порожній або нечитабельний, а також будь-який .env файл, розміщений у public/. В Unix-подібних системах він також перевіряє, чи файл доступний для читання всім користувачам. Він повідомляє про порожній APP_KEY, потім порівнює ключі в .env з .env.example. Це перетинається з інструментами, які перевіряють environment keys у кількох файлах, але Scalpel розглядає неочікувані або відсутні ключі як можливі докази вторгнення. Коли APP_ENV встановлено в production, сканер позначає APP_DEBUG=true. Опція --production застосовує цю перевірку незалежно від значення APP_ENV, а також позначає APP_ENV=local.

Ви можете запустити всі сканери або вибрати підмножину:

php artisan scalpel:scan
php artisan scalpel:scan --only=structural,obfuscated
php artisan scalpel:scan --only=userini

Порівняння з еталоном

Команда scalpel:baseline записує SHA-256 хеш, розмір та час модифікації кожного включеного файлу. Команда scalpel:diff потім порівнює поточні файли з цим записом та повідомляє про додані, змінені та видалені файли:

php artisan scalpel:baseline
php artisan scalpel:diff

Створюйте еталон лише після того, як додаток перебуває в стані, якому ви довіряєте. Поки еталон не існує, scalpel:scan та scalpel:diff повідомляють про MEDIUM знахідку, що вказує на необхідність створити його. Після кожного розгортання проєкт пропонує запустити php artisan optimize, а потім scalpel:baseline --force для заміни старого еталона.

Виключення за замовчуванням пропускають шляхи, що часто змінюються, такі як логи, сесії, скомпільовані views та storage/app. Директорія vendor/ пропускається сканерами вмісту, але залишається частиною порівнянь з еталоном, тому файл, доданий до встановленого пакета, все одно з'явиться в diff.

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

Scalpel може HMAC-підписувати еталони та JSON-звіти, коли SCALPEL_SIGNING_ENABLED встановлено в true, а SCALPEL_SIGNING_KEY містить виділений ключ, який не є вашим APP_KEY. Команда diff перевіряє підписаний еталон перед використанням і повідомляє про недійсний або відсутній підпис як CRITICAL. Це виявляє еталон, регенерований без ключа підпису, але не може захистити еталон, коли зловмисник може прочитати цей ключ або змінити сам сканер. Увімкніть підписування перед створенням першого еталона. Команда scalpel:verify перевіряє підпис збереженого JSON-звіту.

Тестове сканування

Автор статті протестував Scalpel 1.9.0 у свіжому Laravel 13.31 додатку. З правами доступу до .env, встановленими на 0600, та еталоном на місці, стандартне сканування не виявило жодних знахідок.

Потім було додано чотири нешкідливі тестові файли: виклик eval(base64_decode(...)) всередині блоку if (false), файл з назвою avatar.php.jpg, handler mapping у .htaccess та файл .user.ini з auto_prepend_file.

Запуск чотирьох сканерів вмісту зберіг вивід коротким:

php artisan scalpel:scan \
--only=structural,obfuscated,htaccess,userini \
--no-banner

Повне сканування повернуло дев'ять знахідок, оскільки сканер еталона також повідомив про чотири нові файли та змінений файл routes/web.php.

Той самий тест виявив проблему з налаштуваннями за замовчуванням, яку слід врахувати в CI. Запуск php artisan optimize скомпілював framework views у storage/framework/views. Наступне сканування повідомило про 100 MEDIUM знахідок variable-variable та дві HIGH знахідки backtick у цих згенерованих файлах. Після php artisan optimize:clear та повторного створення еталона сканування завершилося без знахідок.

Структурний сканер дозволяє директорію скомпільованих views Laravel, але сканер обфускованого коду все ще читає її вміст. Додаток, який кешує views у production, повинен протестувати цей шлях перед додаванням Scalpel до deployment gate. Додавання storage/framework/views до content_scan_excluded_paths уникає цих знахідок, але за ціну пропуску перевірок вмісту для кожного скомпільованого view.

Вивід CI та Laravel Events

Обидві команди scalpel:scan та scalpel:diff підтримують форматування виводу у вигляді таблиці, JSON, GitHub Actions annotation та SARIF. Опція --fail-on встановлює найнижчу серйозність, що призводить до провалу CI job. За замовчуванням це HIGH.

php artisan scalpel:scan --format=sarif --fail-on=MEDIUM

Код виходу 0 означає, що сканування завершилося і нічого не знайдено. Код 1 означає, що принаймні одна знахідка перебуває на рівні --fail-on severity або вище. Код 2 охоплює знахідки нижче цієї серйозності або незавершене сканування, тому нечитабельна директорія не призводить до чистого статусу.

Після scalpel:scan або scalpel:diff пакет відправляє подію ScanFinished. Подія містить знахідки, команду, що виконувалася (scan або diff), та тривалість у мілісекундах. Додаток може слухати цю подію та відправляти власні mail, Slack або webhook сповіщення без парсингу виводу команди.

Встановлення

Laravel Scalpel вимагає PHP 8.2 або новіше та підтримує Laravel 10-13. Встановіть його через Composer, потім опублікуйте конфігурацію:

composer require hryagstn/laravel-scalpel
php artisan vendor:publish --tag=scalpel-config

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

Ви можете переглянути вихідний код та повний довідник команд на GitHub або спробувати симулятор команд на вебсайті Laravel Scalpel.

3

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

Fresh Package
Новини 19 вересня 2026

Fresh Package: новий скелет для розробки Laravel-пакетів з Testbench, CI та інтеграцією Boost

Fresh Package від Mazen Touati - це сучасний скелет для створення Laravel-пакетів, який включає тестове середовище, статичний аналіз, CI/CD, workbench-додаток та шаблони навичок для AI-агентів. Підтримує як backend-only, так і full-stack пакети.

2
Jev: модель, яка повертає рішення замість тексту - і вже є в Laravel AI SDK Рекомендовано
Новини 18 вересня 2026

Jev: модель, яка повертає рішення замість тексту - і вже є в Laravel AI SDK

TypeSafe AI випустила Jev - модель, яка не генерує текст, а повертає типізовані рішення з каліброваними ймовірностями за 70-500 мс. Через два дні підтримка приїхала в гілку 1.x пакета laravel/ai у вигляді API Classification з питаннями Boolean, Choice і Score.

Пакети за темою

Pest

pestphp/pest

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

11,667 v5.1.1 2

Laravel Dusk

laravel/dusk

Браузерні тести з виразним API: керує справжнім Chrome через ChromeDriver, тож перевіряє і JavaScript, і те, що бачить користувач. Робить скріншоти невдалих тестів автоматично.

1,943 v8.6.0 13 1