Злам сайту рідко починається з витонченої атаки. Verizon у звіті Data Breach Investigations Report 2025 розібрав 22 052 інциденти безпеки, серед яких 12 195 виявилися підтвердженими витоками даних. Експлуатація вразливостей стала початковою точкою проникнення у 20% випадків, і цей показник виріс на 34% порівняно з попереднім звітом. Більшість таких вразливостей відомі заздалегідь, для них існують оновлення та типові налаштування захисту.
Значну частину ризиків для вебпроєкту закриває грамотна конфігурація сервера. Браузер відвідувача вміє блокувати впровадження стороннього коду, вбудовування сторінки в чужі фрейми та спроби перехопити трафік, якщо сервер передає йому відповідні інструкції в HTTP-заголовках. Швидка перевірка сайту показує, які з цих заголовків уже налаштовані на вашому домені і яких бракує. З цього зручно починати аудит, бо результат видно за кілька секунд і він одразу підказує, куди дивитися далі.
Звідки приходять атаки на сайти
Статистику DBIR формують три основні сценарії. Викрадені облікові дані залишаються найпоширенішим способом проникнення з часткою 22%, фішинг тримається на рівні близько 15%. Вразливості у програмному забезпеченні впритул наблизилися до лідера. Для власника інтернет-магазину чи корпоративного сайту це означає, що застаріле ядро CMS, забутий модуль або тестовий скрипт у кореневій папці становлять таку саму загрозу, як слабкий пароль адміністратора.
Окремо варто звернути увагу на стороннє програмне забезпечення. Частка витоків, у яких була задіяна третя сторона, подвоїлася з 15% до 30%. У випадку сайту третя сторона присутня майже скрізь: модулі та плагіни від різних розробників, віджети онлайн-чату, скрипти аналітики, платіжні форми, бібліотеки з CDN. Кожен підключений компонент отримує доступ до сторінки і розширює поверхню атаки. Саме тому захисні механізми рівня браузера, про які йдеться нижче, мають таку велику вагу.
HTTPS як обов’язковий мінімум
Шифрування з’єднання стало нормою для вебу. За даними Web Almanac 2025 від HTTP Archive, HTTPS використовують 97,5% десктопних і 97,3% мобільних сайтів. Встановлений сертифікат захищає трафік після того, як з’єднання вже відкрите за захищеним протоколом. Перший запит користувача, який вводить адресу без префікса https://, браузер може надіслати відкритим каналом, і в цей момент зловмисник у тій самій Wi-Fi-мережі здатен підмінити відповідь.
Цю проблему закриває заголовок Strict-Transport-Security (HSTS). Він наказує браузеру протягом заданого часу звертатися до домену виключно через HTTPS. HSTS присутній на 36% сторінок у мобільній вибірці, близько 40% сайтів з цим заголовком поширюють захист на піддомени, і лише приблизно 22% використовують директиву preload. Рекомендоване значення max-age становить 31536000 секунд, тобто рік. Такий самий мінімальний строк вимагає список hstspreload.org, куди можна внести домен, щоб браузери застосовували HSTS ще до першого візиту. Перед увімкненням includeSubDomains варто переконатися, що всі піддомени, включно зі службовими на кшталт mail. чи dev., мають дійсні сертифікати. Інакше вони стануть недоступними для відвідувачів на весь строк дії політики.
Заголовки, які варто налаштувати на кожному сайті
Набір базових заголовків невеликий, і їх налаштування займає менше години навіть на старому проєкті. Ось що має бути у відповідях сервера:
Strict-Transport-Security примушує браузер використовувати лише HTTPS. Типове значення:
max-age=31536000; includeSubDomainsContent-Security-Policy визначає, з яких джерел сторінка може завантажувати скрипти, стилі, шрифти та фрейми. Це найсильніший засіб проти XSS-атак, про його впровадження детальніше йдеться в наступному розділі.
X-Content-Type-Options зі значенням
nosniffзабороняє браузеру вгадувати тип файлу. Так завантажений користувачем «малюнок» зі шкідливим JavaScript усередині не виконається як скрипт.X-Frame-Options зі значенням
SAMEORIGINабо директиваframe-ancestorsу CSP блокують вбудовування сайту в чужі сторінки і захищають від клікджекінгу.Referrer-Policy зі значенням
strict-origin-when-cross-originобмежує передачу повної адреси сторінки на зовнішні сайти, щоб токени та параметри з URL не потрапляли стороннім сервісам.Permissions-Policy вимикає доступ до камери, мікрофона, геолокації та інших API браузера, якими сайт не користується.
Для Nginx базова конфігурація виглядає так:
server_tokens off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Параметр always гарантує, що заголовки потраплять також у відповіді з кодами помилок 4xx і 5xx. На Apache аналогічний результат дає директива Header always set у конфігурації віртуального хоста або в .htaccess за увімкненого модуля mod_headers. Рядок server_tokens off прибирає з відповіді версію Nginx. Так само варто вимкнути заголовок X-Powered-By, який PHP за замовчуванням додає з номером версії: це робиться параметром expose_php = Off у php.ini. Відкрита версія програмного забезпечення спрощує зловмиснику пошук готового експлойта під конкретну збірку.
Заголовок X-XSS-Protection сучасні браузери вже не підтримують. OWASP рекомендує вимикати його значенням 0 або не надсилати зовсім, оскільки старий фільтр у деяких браузерах сам створював вразливості.
Content Security Policy без поломок сайту
CSP дає найбільший захисний ефект і водночас найважче впроваджується. Частка сайтів із цим заголовком зросла з 18,5% до 21,9% за рік. Низьке поширення пояснюється просто: політика, написана навмання, блокує вбудовані скрипти, лічильники аналітики, пікселі рекламних кабінетів і платіжні віджети, і магазин перестає приймати замовлення.
Безпечний шлях впровадження починається з режиму спостереження. Заголовок Content-Security-Policy-Report-Only з тією самою політикою нічого не блокує. Браузер лише надсилає звіти про порушення на адресу, вказану в директиві report-uri або report-to. За один-два тижні збору звітів стає зрозуміло, які зовнішні домени реально використовує сайт: Google Tag Manager, Meta Pixel, скрипти платіжного шлюзу, CDN зі шрифтами. Після цього формується білий список джерел і заголовок переводиться в активний режим.
Для першої версії політики варто взяти директиви з мінімальним ризиком поломок і максимальним захисним ефектом: object-src 'none' забороняє застарілі плагіни, base-uri 'self' блокує підміну базової адреси посилань, frame-ancestors 'self' захищає від вбудовування у фрейми. Вбудовані скрипти в шаблонах поступово переносяться в окремі файли або отримують криптографічний nonce, який сервер генерує заново для кожної відповіді. Директива 'unsafe-inline' у script-src фактично знімає захист від XSS, тому її присутність у фінальній політиці означає, що роботу не завершено.
Скрипти, які сайт підключає з публічних CDN, варто доповнити атрибутом integrity з хешем файлу (механізм Subresource Integrity). Якщо файл на CDN підмінять, браузер відмовиться його виконувати.
Оновлення, модулі та доступи до адмінпанелі
Заголовки захищають відвідувача в браузері. Сам сервер і CMS потребують окремої дисципліни. Ядро системи керування та всі розширення слід оновлювати з перевіркою на тестовій копії сайту, а модулі, якими ніхто не користується, видаляти повністю. Вимкнений модуль продовжує лежати на сервері, і його вразливі файли залишаються доступними за прямою адресою.
Адмінпанель заслуговує на кілька шарів захисту: двофакторну автентифікацію для всіх облікових записів, нестандартну адресу входу, обмеження доступу за IP-адресою там, де команда працює зі статичних адрес, і окремі акаунти для кожного співробітника та підрядника. Спільний логін «admin» на всю команду унеможливлює розслідування інциденту, бо в журналах не видно, хто саме виконав дію.
Паролі до бази даних, API-токени платіжних систем і SMTP-доступи ніколи не повинні потрапляти в репозиторій. Дослідники Verizon з’ясували, що медіанний час усунення витоку секретів, знайдених у репозиторіях GitHub, становив 94 дні. Файли на кшталт config.php чи .env додаються в .gitignore з першого коміту, а доступ до каталогу .git на продакшн-сервері закривається правилом у конфігурації Nginx або Apache.
Резервні копії працюють за правилом 3-2-1: три копії даних, на двох різних типах носіїв, одна з них поза основним сервером. Копія, що зберігається на тому самому хостингу, зникне разом із сайтом під час атаки шифрувальника або блокування акаунта.
Графік перевірок для власника сайту
Безпека сайту тримається на регулярності. Заголовки відповіді варто перевіряти після кожного оновлення CMS, зміни хостингу, перенесення на CDN чи встановлення нового модуля, оскільки будь-яка з цих змін здатна перезаписати конфігурацію сервера. Щомісяця доцільно переглядати строк дії SSL-сертифіката, журнал оновлень ядра й розширень та звіти CSP про заблоковані ресурси. Раз на квартал проводиться ревізія облікових записів в адмінпанелі, на хостингу та в панелях сторонніх сервісів: доступи колишніх підрядників закриваються, паролі змінюються. Двічі на рік варто розгортати резервну копію на тестовому сервері й переконуватися, що сайт із неї справді відновлюється і працює. Такий графік займає кілька годин на місяць і перетворює безпеку з разового проєкту на звичну частину обслуговування сайту.