Как предотвратить XSS-атаки?php-22

XSS (Cross-Site Scripting) — это инъекция вредоносных скриптов на страницы, которые видят другие пользователи. Вот профессиональные методы защиты.

Основные методы защиты

1. Экранирование вывода

htmlspecialchars() — базовый способ:

echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
  • Преобразует <, >, ", ', & в HTML-сущности
  • Всегда указывайте кодировку (UTF-8)

2. Библиотеки для очистки HTML

HTML Purifier (для сложных случаев):

require_once 'HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);
$cleanHtml = $purifier->purify($dirtyHtml);
  • Удаляет опасные теги/атрибуты
  • Сохраняет безопасную разметку

3. Заголовки Content Security Policy

Пример настройки:

header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com");
  • Запрещает выполнение inline-скриптов
  • Разрешает скрипты только с доверенных источников

4. HTTP-Only и Secure флаги для кук

setcookie('session', $token, [
    'httponly' => true,
    'secure' => true,
    'samesite' => 'Strict'
]);
  • Запрещает доступ к кукам из JavaScript
  • Передача только по HTTPS

Специфичные сценарии защиты

Для JSON API

$data = ['content' => $userContent];
header('Content-Type: application/json');
echo json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
  • Экранирует спецсимволы в JSON

Для атрибутов HTML

$value = htmlspecialchars($data, ENT_QUOTES | ENT_HTML5, 'UTF-8', false);
echo '<div data-value="' . $value . '">...</div>';
  • Двойное экранирование кавычек

Для JavaScript-вставок

$json = json_encode($data, JSON_HEX_TAG);
echo '<script>var data = ' . $json . ';</script>';
  • Никогда не вставляйте данные напрямую в JS

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

  1. Фильтрация ввода:

    $cleanInput = filter_var($input, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
    
  2. Белые списки разрешенных тегов (если нужно сохранить HTML):

    $allowedTags = '<p><a><strong><em>';
    $cleanHtml = strip_tags($html, $allowedTags);
    
  3. Экранирование перед вставкой в DOM:

    function escapeJs($string) {
        return addcslashes($string, "\\\'\"&\n\r<>");
    }
    

Современные практики

  1. Типизированные свойства — снижают риск неожиданных значений
  2. Строгие типы (declare(strict_types=1)) — предотвращают неявные преобразования
  3. Фреймворковые решения:
    • Laravel Blade: {{ $unescaped }} автоматически экранирует
    • Twig: {{ var|escape('html') }}

Резюмируем:

основная защита от XSS — экранирование всех выводимых данных с помощью htmlspecialchars(), использование CSP-заголовков и специальных библиотек для работы с HTML. Никогда не доверяйте пользовательскому вводу и применяйте защиту на всех уровнях приложения — от БД до фронтенда.