← Назад к вопросам

Как валидировать и санитизировать пользовательский ввод?

2.7 Senior🔥 91 комментариев
#PHP Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Общие принципы валидации и санитизации

Валидация и санитизация — это два ключевых этапа обработки пользовательского ввода в PHP приложении. Их цели различаются: валидация проверяет, соответствует ввод заданным правилам (например, формат email, диапазон чисел), а санитизация преобразует ввод для безопасного использования, удаляя или преобразовывая потенциально опасные элементы. Нельзя полагаться только на санитизацию или только на валидацию — это взаимодополняющие процессы.

Валидация (Validation)

Валидация отвечает на вопрос: "Данные корректны и соответствуют ожиданиям?". Она должна выполняться как на клиентской стороне (для UX), так и обязательно на серверной (для безопасности). Основные подходы:

  1. Фильтрация с помощью filter_var(): PHP предоставляет набор фильтров для базовой валидации.

    $email = $_POST['email'];
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        throw new InvalidArgumentException('Некорректный email адрес');
    }
    
    $integer = $_POST['number'];
    $options = ['options' => ['min_range' => 1, 'max_range' => 100]];
    if (!filter_var($integer, FILTER_VALIDATE_INT, $options)) {
        throw new InvalidArgumentException('Число должно быть от 1 до 100');
    }
    
  2. Регулярные выражения (preg_match, preg_replace): Для сложных форматов (телефон, сложный пароль).

    $phone = $_POST['phone'];
    if (!preg_match('/^\+?[0-9\s\-\(\)]{10,20}$/', $phone)) {
        throw new InvalidArgumentException('Некорректный формат телефона');
    }
    
  3. Специализированные библиотеки и валидаторы: Для сложных структур данных часто используются библиотеки, такие как Symfony Validator, или создаются собственные классы-валидаторы, применяющие комбинацию правил.

Санитизация (Sanitization)

Санитизация отвечает на вопрос: "Данные безопасны для дальнейшего использования (в SQL, HTML, etc)?". Она трансформирует данные, но не гарантирует их корректность. Ключевые направления:

  1. Для работы с базами данных (SQL Injection):
    *   **Использование Prepared Statements (PDO или mysqli)** — это НЕ санитизация, но самый надежный метод предотвращения инъекций. Санитизация здесь часто сводится к проверке типов.
```php
$pdo = new PDO($dsn, $user, $pass);
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
// Значение автоматически обрабатывается драйвером DB
$stmt->execute(['email' => $_POST['email']]);
```

2. Для вывода в HTML (XSS Prevention):

    *   **Функция `htmlspecialchars()`** — преобразует специальные символы в HTML-сущности.
```php
$userComment = $_POST['comment'];
// Конвертирует <, >, &, " в безопасные сущности
$safeOutput = htmlspecialchars($userComment, ENT_QUOTES, 'UTF-8');
echo "<div>" . $safeOutput . "</div>";
```
    *   **Более сложная очистка (например, от тегов `<script>`)** может потребовать библиотек типа **HTML Purifier**.

  1. Для обработки файлов и путей: Использование basename() для удаления нежелательных компонентов пути, валидация MIME-типов загружаемых файлов.

Практические рекомендации и стратегии

  • Валидировать и санитизировать как можно раньше: Лучше сразу при получении данных в контроллере или специализированном сервисе.
  • Разделять логику: Валидацию часто выносят в отдельные классы/объекты (DTO с валидацией), санитизацию — в зависимости от контекста использования (например, отдельный метод для подготовки данных к SQL).
  • Не доверять данным из $_GET, $_POST, $_COOKIE: Всегда рассматривайте их как потенциально опасные.
  • Сочетать несколько методов: Например, для поля "цена":
    *   Валидация: проверка, что это число в диапазоне от 0 до 10000 (`filter_var` с `FILTER_VALIDATE_FLOAT`).
    *   Санитизация для SQL: использование prepared statement.
    *   Санитизация для HTML (если вдруг нужно вывести): применение `htmlspecialchars`.
  • Использовать современные фреймворки: Большинство (Laravel, Symfony) предоставляют мощные, интегрированные инструменты для валидации через Form Request Objects, Validation Constraints, которые автоматически применяют многие лучшие практики.
  • Создавать white-листы (списки разрешенных значений): Это часто более безопасно, чем black-листы (списки запрещенного). Например, для поля "статус" принимайте только значения из известного массива ['active', 'pending', 'closed'].

Важное правило: Санитизация зависит от контекста использования данных. Один набор санитизации для SQL, другой для HTML, третий для использования в качестве имени файла. Поэтому универсальной "санитизации на все случаи" не существует — нужно понимать, где и как данные будут использоваться.

Как валидировать и санитизировать пользовательский ввод? | PrepBro