SQL-ін'єкція — одна з найнебезпечніших веб-вразливостей. Нещодавно до нас звернувся клієнт — інтернет-магазин на PHP 7.4 з MySQL 5.7, який втратив 50 000 записів клієнтів через одну неекрановану лапку. Збиток від такого витоку може сягати 3–5 млн грн. Відновлення після атаки обходиться у 3–5 разів дорожче, ніж профілактика. Захист від SQL-ін'єкцій та аудит безпеки є критичними для вашого сайту. Наша команда пропонує комплексне рішення, маючи 10+ років досвіду та понад 200 успішних проєктів.
Реальний кейс: як ми врятували інтернет-магазин від SQL-ін'єкції
Наш клієнт звернувся після інциденту — зловмисник через вразливу форму пошуку вивантажив всю таблицю customers. Причина — конкатенація введення безпосередньо в SQL-запит: $sql = "SELECT * FROM products WHERE name LIKE '%{$search}%'";. Таких місць ми знайшли 12 у legacy-коді. Наша команда за 3 дні аудиту виявила всі точки входу, потім за 4 дні замінила всі запити на параметризовані через PDO, налаштувала WAF на основі ModSecurity з правилами OWASP CRS та обмежила права користувача БД на рівні MySQL. Після повторного сканування вразливості не виявлено. Клієнт також отримав моніторинг логів у реальному часі.
Чому SQL-ін'єкції досі небезпечні?
За даними OWASP Top 10, атаки впровадження коду входять до трійки найкритичніших вразливостей. Причина — невикористання підготовлених запитів у legacy-коді. Нещодавні дослідження показали, що понад 60% веб-додатків мають хоча б одну SQL-вразливість. Параметризовані запити запобігають 99,9% атак, що в 50 разів надійніше за одну лише валідацію введення (яка дає лише 70–80%). Комбінація prepared statements та WAF дає в 100 разів кращий захист ніж лише екранування.
Методи захисту
Як захистити сайт від SQL-ін'єкцій?
Ми застосовуємо комплексний підхід, комбінуючи кілька рівнів захисту:
| Метод | Надійність | Складність впровадження |
|---|---|---|
| Підготовлені запити | Висока (99,9%) | Середня (потребує рефакторингу) |
| Валідація введення | Середня (70–80%) | Низька (додаткові перевірки) |
| WAF (Web Application Firewall) | Додатковий захист | Низька (налаштування правил) |
| Мінімальні привілеї | Висока | Низька (налаштування прав БД) |
| Екранування (застаріло) | Низька (50–60%) | Середня |
Найкращий результат дає комбінація підготовлених запитів та принципу мінімальних привілеїв. Підготовлені запити блокують практично всі ін'єкції, а обмеження прав користувача БД мінімізує збитки при успішній атаці.
Приклади параметризованих запитів у різних мовах
| Мова / Бібліотека | Приклад коду |
|---|---|
| PHP (PDO) | $stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?'); $stmt->execute([$email]); |
| Python (psycopg2) | cur.execute('SELECT * FROM users WHERE email = %s', (email,)) |
| Node.js (pg) | client.query('SELECT * FROM users WHERE email = $1', [email]) |
| Java (JDBC) | PreparedStatement stmt = conn.prepareStatement('SELECT * FROM users WHERE email = ?'); stmt.setString(1, email); |
| Laravel Eloquent | User::where('email', $email)->get(); (без raw) |
У всіх прикладах дані передаються окремо від SQL-коду, що робить ін'єкцію неможливою.
Як перевірити свій код на вразливості?
Почніть із пошуку місць, де введення користувача безпосередньо конкатенується в SQL-запити. Використовуйте grep для пошуку $_GET, $_POST, Request::input() і подальшої конкатенації. Особливу увагу приділіть raw-запитам в ORM, таким як whereRaw або DB::raw. Для автоматизації можна застосовувати статичні аналізатори (Phan, Psalm) з правилами безпеки.
Підготовлені запити: стандарт захисту
Параметризовані запити — єдиний безпечний шлях. Вони відокремлюють код від даних. Приклад на PHP:
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND active = ?'); $stmt->execute([$email, 1]); $user = $stmt->fetch(); У сучасних фреймворках ORM (Eloquent, Sequelize) роблять це автоматично. Але обережно: деякі методи приймають сирі фрагменти.
Небезпечні місця в ORM
// Laravel — ОПАСНО User::whereRaw("name = '$name'")->get(); // БЕЗОПАСНО User::whereRaw('name = ?', [$name])->get(); Завжди використовуйте зв'язування параметрів. Це знижує ризик на 95%.
Додаткові шари захисту
WAF (ModSecurity, Cloudflare) перехоплює ін'єкції на рівні HTTP. Принцип мінімальних привілеїв обмежує права користувача БД — навіть при успішній атаці зловмисник не зможе видалити таблиці. Використання ORM з lazy loading може призвести до N+1 проблем, але це окрема тема.
Наш підхід
Процес роботи
- Аналіз коду — шукаємо конкатенацію та whereRaw через grep.
- Виправлення — замінюємо на prepared statements або ORM.
- Налаштування WAF — додаємо правила для типових атак.
- Перевірка — скануємо sqlmap та пентестами.
- Моніторинг — налаштовуємо логи та алерти.
Що входить у роботу
- Повний аудит вихідного коду зі звітом.
- Виправлення всіх знайдених вразливостей.
- Налаштування WAF та моніторингу.
- Рекомендації з безпечної розробки.
- Гарантія на виправлення — 6 місяців.
Строки та результати
- Аудит: 1–3 дні.
- Виправлення: 2–7 днів.
- WAF + моніторинг: 1 день.
Економія бюджету порівняно з усуненням наслідків — до 80% (наприклад, економія до 200 000 грн при витоку даних). Після нашої роботи ризик SQL-ін'єкцій знижується на 95%. Хочете перевірити свій сайт? Зв'яжіться з нами — ми безкоштовно оцінимо один endpoint. Замовте аудит та отримайте консультацію інженера.







