# 09. Безопасность
[← Оглавление](./index.md)
---
## ORM вместо raw SQL — никаких переменных в строке запроса
**ПЛОХО — SQL-ИНЪЕКЦИЯ ДАЖЕ С FORSQL**
```php
global $DB;
$email = $_GET['email'];
$sql = "SELECT * FROM b_user WHERE EMAIL = '" . $DB->ForSql($email) . "'";
$res = $DB->Query($sql);
```
**ХОРОШО — ORM С ПАРАМЕТРИЗОВАННЫМ ЗАПРОСОМ**
```php
use Bitrix\Main\UserTable;
$email = $_GET['email'] ?? '';
$user = UserTable::query()
->setSelect(['ID', 'NAME', 'LAST_NAME'])
->where('EMAIL', $email) // параметр передаётся безопасно
->setLimit(1)
->exec()
->fetch();
```
---
## Экранирование вывода в HTML
**ПЛОХО — XSS УЯЗВИМОСТЬ**
```php
echo "Привет, " . $arUser['NAME'];
```
**ХОРОШО — HTMLFILTER::ENCODE()**
```php
use Bitrix\Main\Text\HtmlFilter;
echo "Привет, " . HtmlFilter::encode($arUser['NAME']);
```
---
## Валидация входящих данных
`FILTER_SANITIZE_SPECIAL_CHARS` и `FILTER_SANITIZE_STRING` удалены в PHP 8.1–8.2. Используйте явную санитизацию.
**ПЛОХО — УДАЛЁННЫЕ КОНСТАНТЫ PHP**
```php
// FILTER_SANITIZE_SPECIAL_CHARS удалён в PHP 8.2!
$phone = filter_input(INPUT_POST, 'PHONE', FILTER_SANITIZE_SPECIAL_CHARS);
```
**ХОРОШО — ЯВНАЯ САНИТИЗАЦИЯ ДЛЯ PHP 8.2+**
```php
$phone = trim((string)($_POST['PHONE'] ?? ''));
$phone = strip_tags($phone);
if (!preg_match('/^\+?\d{10,15}$/', $phone)) {
throw new \InvalidArgumentException('Некорректный номер телефона');
}
// Для email — нативный PHP-фильтр (не удалён):
$email = filter_input(INPUT_POST, 'EMAIL', FILTER_VALIDATE_EMAIL);
if ($email === false || $email === null) {
throw new \InvalidArgumentException('Некорректный email');
}
```