> Какие угрозы безопасности существуют при работе с данными в SQL (PHP)

Уровень: senior · Роль: backend · Язык: PHP · Категория: Технические вопросы

Компании: vanta

Стек: PHP

> Пример ответа

Короткий ответ

Основные угрозы при работе с SQL - это SQL-инъекции, утечка данных через недостаточное разграничение доступа, перехват трафика при отсутствии шифрования, а также риски, связанные с некорректной обработкой ошибок, которые раскрывают структуру БД. Дополнительно стоит учитывать угрозы целостности данных (например, гонки при конкурентном доступе) и проблемы с резервным копированием. Для backend-разработчика на PHP критически важна защита от инъекций через подготовленные выражения и строгая валидация входных данных.

Подробное объяснение

SQL-инъекции - главная угроза. Возникают, когда пользовательский ввод конкатенируется в запрос без экранирования. Атакующий может модифицировать запрос: получить чужие данные, удалить таблицы, выполнить произвольные команды через stacked queries (если драйвер поддерживает).

Вторая группа угроз - недостаточный контроль доступа на уровне приложения. Даже если SQL-инъекция закрыта, можно получить доступ к данным другого пользователя через неверные условия WHERE (например, отсутствие user_id в запросе).

Третья - утечка данных через ошибки. PDO и mysqli по умолчанию выводят сообщения об ошибках, которые содержат SQL-запросы и структуру таблиц. В production это должно быть отключено.

Четвертая - перехват данных при передаче. Если соединение с БД не зашифровано (не TLS), данные могут быть прочитаны в локальной сети.

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

Шестая - SQL-инъекции через second-order: данные, сохраненные ранее, используются в запросах без повторной санитизации.

На практике

Для PHP-разработчика на практике важно:

  • Использовать PDO с prepared statements - это закрывает основной вектор инъекций.
  • Не доверять данным из суперглобалей $_GET, $_POST, $_COOKIE - всегда фильтровать по типу и длине.
  • Для динамических идентификаторов (например, сортировка по колонке) использовать whitelist допустимых значений, а не подстановку напрямую.
  • Включать PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION в development, но в production логировать ошибки в файл, а пользователю отдавать generic message.
  • Использовать транзакции для операций, которые должны быть атомарными.
  • Для шифрования соединения с MySQL использовать PDO::MYSQL_ATTR_SSL_CA и соответствующие параметры.
  • Ограничивать права SQL-пользователя приложения: только SELECT/INSERT/UPDATE/DELETE на нужных таблицах, без DROP, ALTER, GRANT.

Пример кода

PHP
// Безопасный запрос с prepared statement
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email AND status = :status');
$stmt->execute([
'email' => $_POST['email'],
'status' => 'active',
]);
$user = $stmt->fetch();
// Динамическая сортировка через whitelist
$allowedColumns = ['name', 'created_at', 'email'];
$sortColumn = $_GET['sort'] ?? 'created_at';
if (!in_array($sortColumn, $allowedColumns, true)) {
$sortColumn = 'created_at';
}
$stmt = $pdo->query("SELECT * FROM users ORDER BY `$sortColumn` LIMIT 10");
// Транзакция для атомарности
$pdo->beginTransaction();
try {
$pdo->exec('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
$pdo->exec('UPDATE accounts SET balance = balance + 100 WHERE id = 2');
$pdo->commit();
} catch (Throwable $e) {
$pdo->rollBack();
throw $e;
}

Как отвечать на собеседовании

Начните с SQL-инъекций как самой критичной угрозы, затем перечислите остальные. Покажите понимание, что безопасность - это не только экранирование, но и архитектура: права доступа, шифрование, обработка ошибок. Упомяните, что prepared statements решают проблему инъекций, но не заменяют валидацию данных. Приведите пример из реального проекта, где вы сталкивались с угрозой и как её закрыли. Если спросят про конкретные функции PHP, упомяните PDO::quote как fallback, но подчеркните, что это не лучший подход.

Что проверяет интервьюер

Проверяется глубина понимания: знает ли кандидат только про инъекции или видит полную картину. Оценивается умение объяснить trade-off между удобством и безопасностью, знание особенностей PDO и mysqli, понимание, почему нельзя полагаться на mysql_real_escape_string. Также проверяется практический опыт: как кандидат настраивает окружение, обрабатывает ошибки, проектирует запросы. Важно, чтобы кандидат мог обосновать выбор prepared statements и рассказать про edge cases (например, LIKE с подстановочными знаками).

Типичные ошибки

  • Ответ только про SQL-инъекции, без упоминания других угроз.
  • Утверждение, что mysqli_real_escape_string - достаточная защита.
  • Игнорирование проблемы с выводом ошибок в production.
  • Отсутствие упоминания про транзакции и целостность данных.
  • Предложение использовать хранимые процедуры как панацею - это не решает проблему инъекций.
  • Непонимание разницы между prepared statements и простым экранированием.
  • Забывают про second-order injection, когда данные из БД используются в новых запросах без повторной обработки.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью