# Безопасность и экранирование ← [Назад к разделу БД](README.md) Главная защита от SQL-инъекций — **плейсхолдеры**. Ручное экранирование нужно лишь в редких случаях (динамический SQL, который нельзя выразить плейсхолдером). --- ## Правило №1 — плейсхолдеры ```php // ХОРОШО — значение экранируется QueryBuilder DB::query('SELECT * FROM p WHERE title = %s AND rubric_id = %i', $title, $rid); // ОПАСНО — прямая склейка пользовательского ввода DB::query("SELECT * FROM p WHERE title = '$title'"); // ← SQL-инъекция ``` Полный список плейсхолдеров — [placeholders.md](placeholders.md). --- ## Ручное экранирование (когда без него никак) | Метод | Что делает | | --- | --- | | `DB::escape($value)` | Экранировать строку (без кавычек). | | `DB::quote($value)` | Экранировать **и** обернуть в кавычки. | | `DB::safe($value)` | Безопасное приведение значения. | ```php $name = DB::quote($userInput); // 'экранированное_значение' DB::query('... WHERE name = ' . $name); ``` > Если можно выразить через `%s`/`%i`/`%li` — делайте это, а не ручной `quote`. --- ## Имена таблиц и полей Идентификаторы (имена таблиц/колонок) **нельзя** параметризовать как значения — для них есть `%b` / `%lb` (оборачивают в обратные кавычки) и [резолверы имён таблиц](tables.md). ```php DB::query('SELECT * FROM %b WHERE %b = %i', $table, $column, $id); ``` Если имя поля приходит извне (например, «искать по выбранному полю») — **сверяйте с белым списком** допустимых полей перед подстановкой, даже с `%b`. ```php $allowed = array('title', 'article', 'alias'); if (!in_array($field, $allowed, true)) { $field = 'title'; } DB::query('SELECT * FROM p WHERE %b LIKE %ss', $field, $q); ``` --- ## `%l` — сырое значение `%l` вставляет значение **как есть**, без экранирования. Используйте только для доверенных, программно сформированных фрагментов (например, заранее собранных условий), никогда — для пользовательского ввода. --- ## Чек-лист - [ ] Все значения — через плейсхолдеры (`%i`, `%s`, `%ss`, `%li`, …). - [ ] Имена таблиц — через резолверы; имена полей — через `%b` + whitelist. - [ ] Никакой конкатенации `$_GET/$_POST` в строку SQL. - [ ] `%l`/`safe` — только для доверенных данных. - [ ] На запись, меняющую состояние (POST) — проверка CSRF на уровне контроллера.