PAS7 Studio

SQL-ін'єкція без міфів: як знайти вразливість у проєкті та закрити її

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

01 серп. 2026 р.· 10 хв читання· Технології
Кому підійдеBackend engineersFull-stack teamsTech leadsQA engineersProduct owners
Темна абстрактна ілюстрація кібербезпеки з шарами захисту бази даних

Уявімо пошук товарів. Програма хоче виконати SELECT * FROM products WHERE name = ?. Якщо значення передається як параметр, база отримує окремо шаблон запиту й окремо значення. Якщо ж розробник склеює рядок вручну, введення може змінити структуру WHERE, додати іншу умову або завершити команду.

SQLi — це вразливість інтерпретації: trusted code і untrusted data змішалися в одному рядку. [1]
Наслідки залежать від прав DB-користувача: від витоку одного запису до читання, зміни або видалення значної частини даних.
Виправлення починається з parameterization, але не закінчується нею: потрібні least privilege, логування і regression tests. [1]
Досліджуйте власний staging або лабораторії PortSwigger; не перевіряйте чужі системи без письмового дозволу. [5]
01

Користувач контролює значення

Це може бути не лише form field: query string, JSON, cookie, заголовок, імпорт CSV, webhook, параметр сортування або значення з черги. Якщо джерело можна змінити ззовні, вважайте його untrusted.

02

Значення склеюють із SQL

Проблема з'являється в query = '... ' + input + ' ...', template string, raw query builder або ORM-методі, який приймає готовий SQL. Валідація формату сама по собі не замінює параметризацію.

03

DB engine бачить не дані, а синтаксис

Спеціальні символи та фрагменти SQL можуть змінити умову, об'єднати результати, вплинути на час відповіді або перетворити read-операцію на write-операцію — залежно від драйвера й прав.

04

Помилка виходить за межі одного endpoint

Якщо один connection user має надмірні права, компрометація endpoint може зачепити таблиці, звіти, персональні дані, резервні копії або інші tenant-и.

Ментальна модель

Питайте не «чи є тут ORM?», а «чи може зовнішнє значення вплинути на структуру SQL і з якими правами виконується цей запит?».

Цифри нижче потрібно читати чесно. OWASP рахує широку категорію Injection, куди входять SQLi, XSS та інші CWE, а MITRE оцінює слабкість CWE-89 за даними CVE. Це не відсоток усіх атак у світі й не порівняння мов між собою.

274 228

загальних occurrences для категорії Injection у наборі даних OWASP; середня incidence rate — 3,37%. [2]

№2

SQL Injection посіла друге місце у MITRE CWE Top 25 за 2025 рік, score — 28,72. [3]

94%

застосунків у дослідженні OWASP тестувалися на певну форму injection. [2]

Що це означає для команди

SQLi — зріла, добре описана проблема, але її зрілість не робить legacy-код безпечним. Висока відтворюваність — перевага для захисту: патерни легко перевіряти статичним аналізом і тестами.

Почніть із data-flow, а не зі списку фреймворків: знайдіть джерело зовнішнього значення, шлях до data-access layer і фактичний виклик драйвера.

Пошук небезпечних sink-ів

Знайдіть query, execute, raw, text, literal, sequelize.query, knex.raw, jdbc.Statement, SqlCommand та еквіваленти. Перевірте, чи отримують вони склеєний рядок.

Перевірка dynamic SQL

Особливо уважно перегляньте ORDER BY, назви колонок/таблиць, report builder і фільтри. Для них часто не можна використати bind variable — застосуйте allow-list mapping із фіксованих значень. [1]

ORM escape hatches

Перегляньте raw SQL, unsafe operators, custom scopes, string-based filters і міграції. ORM знижує ризик лише там, де команда не обходить його параметризований API.

Не забудьте неочевидні entry points

Адмінка, імпорт, cron, інтеграції, GraphQL resolvers, search endpoints і внутрішні API теж приймають дані, які можуть бути скомпрометовані раніше в ланцюжку.

Перевірте error handling

SQL stack trace, назва таблиці, тип драйвера або різні помилки для різних умов полегшують діагностику атаки. Зовні повертайте безпечну помилку, деталі залишайте в correlation-id логах.

Немає чесного рейтингу «найнебезпечнішої мови»: SQLi можлива майже всюди, де є SQL і небезпечний API. Різниця — у тому, наскільки легко випадково перейти з параметризованого шляху на raw SQL.

ЕкосистемаТипова точка ризикуБезпечний defaultЩо перевірити
PHP: Laravel / SymfonyDB::raw, query string, старий mysqli/PDO-кодQuery Builder/Eloquent bindings, PDO prepared statementsraw(), bind parameters, legacy controllers
JavaScript / TypeScript: Node.jspg/mysql2 query з template string, knex.raw, Sequelize rawdriver placeholders, Prisma parameters, query builder$queryRawUnsafe, raw(), dynamic filters
Python: Django / SQLAlchemycursor.execute з конкатенацією, text() із рядкомDjango QuerySet, SQLAlchemy bound parametersextra(), raw(), literal SQL, f-strings
Java: Spring / HibernateStatement, String concatenation, HQL з inputPreparedStatement, JPA parameters, named parameterscreateNativeQuery, HQL interpolation
.NET: ASP.NET / EF CoreFromSqlRaw або SqlCommand із рядкомLINQ, FromSqlInterpolated, параметриRaw methods, interpolated SQL, DB role
Go / Rustdatabase/sql або client API з побудовою рядкаQueryContext/Execute з placeholders, sqlx bindfmt.Sprintf, format!, dynamic identifiers

Висновок по стеку

Найбільший ризик мають не мови, а команди, які змішують user input із query text, дозволяють raw SQL без review або дають застосунку роль DBA.

Небезпечно: рядок знає забагато

TS
const sql = `SELECT * FROM users WHERE email = '${email}'`;
const result = await db.query(sql);

Тут email стає частиною SQL-тексту. Навіть якщо зараз це «лише пошук», той самий патерн легко копіюють у login, export або admin-функцію.

Безпечніше: драйвер відділяє значення

TS
const result = await db.query(
  "SELECT * FROM users WHERE email = $1",
  [email],
);

Текст запиту фіксований, а email переданий як параметр. Формат placeholder відрізняється між драйверами, тому використовуйте документацію саме свого client library.

Для sort field — не bind, а mapping

TS
const columns = { newest: "created_at", price: "price" } as const;
const column = columns[input] ?? columns.newest;
const sql = `SELECT * FROM products ORDER BY ${column}`;

Назва колонки не є звичайним значенням для bind parameter. Дозволяйте тільки ключі з allow-list і ніколи не підставляйте raw input напряму.

Жоден інструмент не бачить усю картину. Найкращий результат дає комбінація аналізу коду, тесту endpoint-ів і спостереження за runtime.

CodeQL

SAST для пошуку data-flow від user input до SQL sink у JavaScript/TypeScript, Python, Java, C# та інших підтриманих мовах. Додайте в CI й переглядайте findings разом із кодовласником.

Semgrep

Швидкі pattern/data-flow правила для локальної перевірки й pre-commit. Добре підходить, щоб заборонити конкретні небезпечні виклики на кшталт raw query без параметрів.

Burp Suite / OWASP ZAP

DAST для staging: проксі, повторення запитів, активне й пасивне сканування. Запускайте лише в межах дозволеного scope і не вмикайте руйнівні checks на production.

PortSwigger Web Security Academy

Безпечне навчальне середовище з SQLi labs: error-based, blind, UNION та інші сценарії. Корисно для команди, щоб побачити атаку руками без ризику для клієнтських даних.

Sentry / DB audit logs / WAF

Сигнали експлуатації: сплески 4xx/5xx, незвичні latency, помилки парсингу SQL, масові SELECT, дивні user-agent і доступ до нетипових таблиць. WAF — шар зниження ризику, не patch коду.

OWASP радить не покладатися на один фільтр. Зберіть defense-in-depth baseline і зафіксуйте його в Definition of Done.

Параметризовані запити або безпечні stored procedures; dynamic SQL — лише з allow-list і окремим review. [1]

Не використовуйте escaping як основний захист: OWASP прямо вважає його крихким і радить лише як крайній варіант для legacy. [1]

Окремий DB-користувач для застосунку, мінімальні SELECT/INSERT/UPDATE права, без DBA/owner ролі; для read-only flow — read-only account або view. [1]

Секрети й production data не мають потрапляти в логи. Логуйте подію, endpoint, actor, request-id і policy result, але не повний SQL із персональними параметрами.

Додайте negative tests: quote у звичайному імені, довгий рядок, unicode, неправильний тип, невідомий sort key, cross-tenant ID і boundary values.

Тримайте driver, ORM і database engine оновленими, але не вважайте patch dependency заміною secure query construction.

0–1 година

Зупинити розширення шкоди

Зафіксуйте endpoint, час, request-id і scope. За потреби тимчасово вимкніть функцію, обмежте route або поверніть DB role до read-only. Не видаляйте логи й не запускайте експерименти на production.

Того ж дня

Закрити root cause

Замініть string-built SQL на parameterized API, додайте allow-list для identifiers, перевірте права DB user і створіть regression test, який падає на старій реалізації.

Після patch

Перевірити blast radius

Проаналізуйте DB audit logs, незвичні exports, зміни даних, service accounts і доступ до інших tenant-ів. Зафіксуйте, які дані могли бути прочитані або змінені.

До закриття інциденту

Покращити процес

Додайте SAST/DAST у CI, правило review для raw queries, least-privilege migration і короткий playbook для команди. Інакше наступна SQLi з'явиться в іншому endpoint.

Чи захищає ORM від SQL-ін'єкції?

ORM зазвичай параметризує стандартні запити, але не захищає автоматично raw SQL, небезпечні оператори, dynamic identifiers або кастомний query builder. Перевіряйте escape hatches і правила команди.

Чи достатньо перевірити, що поле містить лише цифри?

Це корисна валідація формату, але не універсальний захист. Основним захистом для значень мають бути параметризовані запити; для імен таблиць, колонок і сортування — фіксований allow-list mapping.

Чи може SQLi бути в GraphQL?

Так. GraphQL змінює форму API, але resolver усе одно може передавати аргумент у небезпечний SQL, filter або raw query. Тестуйте data-flow від resolver arguments до DB client.

Чи вирішує проблему WAF?

WAF може блокувати відомі патерни й знизити ймовірність експлуатації, але не виправляє query construction і не гарантує покриття обфускацій та business-specific шляхів. Patch, least privilege і тести все одно потрібні.

Як безпечно навчатися SQLi?

Використовуйте локальний sandbox, OWASP Juice Shop, WebGoat або PortSwigger Academy. Не тестуйте сторонній сайт, API клієнта чи production без чітко погодженого scope і правил тесту.

Перевірено: 01 серп. 2026 р.Актуально для: Web applicationsАктуально для: REST APIsАктуально для: GraphQL APIsАктуально для: Background jobsАктуально для: Admin panelsПеревірено з: OWASP Top 10:2021Перевірено з: CWE Top 25:2025Перевірено з: OWASP SQL Injection Prevention Cheat Sheet

PAS7 Studio може провести code review і security audit для API, адмін-панелі та data-access layer: знайти raw SQL, перевірити tenant boundaries, налаштувати SAST/DAST у CI, зменшити DB-права й підготувати план виправлень із пріоритетами.

Пов'язані статті

ai-assistants

Скільки коштує розробка AI асистента у 2026: RAG чатбот, база знань, CRM, Telegram та підтримка

Практичний гід для бізнесу: від чого залежить ціна розробки AI асистента у 2026 році, що входить у RAG чатбот, інтеграції з CRM, Telegram, guardrails, оцінювання, моніторинг і супровід.

blogs

AI-assisted attacks і prompt injection у 2026: нова поверхня атак для продуктів з AI

Практичний гайд з безпеки AI-функцій: prompt injection, tool abuse, excessive agency, RAG poisoning, data leakage, output handling, human approval gates і permissions для AI agents.

blogs

AI для розробки лендінгів: де він реально прискорює запуск, а де псує конверсію

Дослідження про використання AI у розробці лендінгів: v0, Webflow AI, Builder.io, Framer-подібні AI builders, генерація UX, copy, SEO, персоналізація, A/B тести, ризики шаблонності, безпеки, доступності та технічного боргу.

growth

AI SEO / GEO у 2026: ваші наступні клієнти — не люди, а агенти

Пошук зміщується від кліків до відповідей. Боти та AI-агенти сканують, цитують, рекомендують і дедалі частіше купують. Дізнайтесь, що таке AI SEO / GEO, чому класичного SEO вже недостатньо, і як PAS7 Studio допомагає брендам перемагати у «агентному» вебі.

Професійна розробка для вашого бізнесу

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