> Какой базовый принцип безопасности при работе с пользовательскими данными (PHP)

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

Компании: vanta

Стек: PHP

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

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

Базовый принцип - никогда не доверять пользовательским данным. Любые входные данные (формы, query-параметры, заголовки, файлы) считаются небезопасными, пока не пройдут валидацию и санитизацию. Это включает защиту от SQL-инъекций, XSS, CSRF и других атак. В PHP это означает использование prepared statements для БД, htmlspecialchars для вывода, фильтрацию входных данных и правильную настройку сессий.

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

Принцип "never trust user input" лежит в основе всей веб-безопасности. Пользовательские данные - это любой ввод, который приходит извне: $_GET, $_POST, $_COOKIE, $_FILES, HTTP-заголовки, даже данные из внешних API.

Основные угрозы при работе с пользовательскими данными в PHP:

  • SQL-инъекции - когда данные попадают в SQL-запрос без экранирования
  • XSS (Cross-Site Scripting) - когда данные выводятся в HTML без экранирования
  • CSRF (Cross-Site Request Forgery) - когда запросы от имени пользователя выполняются без проверки источника
  • Path traversal - когда данные используются для работы с файловой системой
  • RCE (Remote Code Execution) - когда данные попадают в eval, system, exec и подобные функции

Базовый принцип включает три этапа:

  1. Валидация - проверка, что данные соответствуют ожидаемому формату (тип, длина, диапазон, регулярное выражение)
  2. Санитизация - очистка или преобразование данных для безопасного использования в конкретном контексте
  3. Экранирование на выходе - данные должны быть экранированы в момент вывода, а не при вводе

Важно понимать: санитизация при вводе не решает проблему полностью. Данные должны быть безопасны в контексте использования. Например, для SQL - prepared statements, для HTML - htmlspecialchars, для URL - urlencode.

На практике

В PHP на практике это выглядит так:

  • Использовать PDO или mysqli с prepared statements вместо конкатенации строк в SQL
  • Использовать htmlspecialchars() или htmlentities() при выводе данных в HTML
  • Использовать filter_input() или filter_var() для валидации входных данных
  • Проверять CSRF-токены в POST-запросах
  • Не использовать функции eval(), exec(), system() с пользовательскими данными
  • Использовать password_hash() и password_verify() для паролей, никогда не хранить их в открытом виде

Пример кода

PHP
// Плохо: конкатенация в SQL
$sql = "SELECT * FROM users WHERE email = '" . $_POST['email'] . "'";
// Хорошо: prepared statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$_POST['email']]);
// Плохо: вывод без экранирования
echo "Привет, " . $_GET['name'];
// Хорошо: экранирование при выводе
echo "Привет, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
// Валидация входных данных
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
// обработка ошибки валидации
}
// CSRF-защита
session_start();
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('Invalid CSRF token');
}

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

Начни с формулировки принципа: "никогда не доверяй пользовательским данным". Затем перечисли основные угрозы: SQL-инъекции, XSS, CSRF. Объясни разницу между валидацией и санитизацией. Подчеркни, что экранирование должно происходить на выходе, в контексте использования. Приведи конкретные примеры из PHP: prepared statements, htmlspecialchars, filter_var. Если спросят про пароли - упомяни password_hash и password_verify.

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

Интервьюер проверяет:

  • Понимание базового принципа безопасности, а не заученные ответы
  • Знание конкретных уязвимостей и способов защиты
  • Умение объяснить, почему санитизация на входе недостаточна
  • Понимание контекста экранирования (SQL vs HTML vs URL)
  • Практические навыки работы с PDO, filter_var, htmlspecialchars
  • Понимание CSRF и методов защиты от него

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

  • Ответ "нужно экранировать данные" без объяснения контекста
  • Утверждение, что mysql_real_escape_string или addslashes решают проблему SQL-инъекций
  • Путаница между валидацией и санитизацией
  • Утверждение, что данные нужно санитизировать при вводе - это неверно, экранировать нужно при выводе
  • Игнорирование CSRF-защиты
  • Предложение использовать htmlspecialchars для SQL-запросов или наоборот
  • Отсутствие упоминания prepared statements как основного способа защиты от SQL-инъекций

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

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