Что такое XSS (Cross-Site Scripting)?

Ответ

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

Основные типы XSS:

  1. Хранимый (Stored/Persistent): Вредоносный скрипт сохраняется на сервере (например, в базе данных, комментариях, профиле) и выполняется каждый раз при загрузке страницы.
  2. Отражённый (Reflected): Скрипт передаётся как часть запроса (часто в URL) и немедленно отражается в ответе сервера. Для эксплуатации требуется, чтобы пользователь перешёл по специально сформированной ссылке.
  3. DOM-based: Уязвимость существует исключительно в клиентском коде (JavaScript). Данные из источника, контролируемого злоумышленником (например, document.location.hash), используются для динамического изменения DOM без безопасной обработки.

Пример уязвимого кода (PHP):

// Опасный код: пользовательский ввод выводится напрямую
echo '<div>Привет, ' . $_GET['username'] . '!</div>';

Если параметр запроса будет ?username=<script>stealCookies()</script>, скрипт выполнится в браузере жертвы.

Методы защиты:

  • Экранирование (Output Encoding): Всегда экранируйте данные перед вставкой в HTML-контекст.
    // Использование htmlspecialchars для экранирования HTML-сущностей
    echo '<div>Привет, ' . htmlspecialchars($_GET['username'], ENT_QUOTES | ENT_HTML5, 'UTF-8') . '!</div>';
  • Content Security Policy (CSP): Используйте HTTP-заголовок Content-Security-Policy, чтобы явно указать браузеру, откуда разрешена загрузка и выполнение скриптов, стилей и других ресурсов. Это эффективный барьер даже при успешной инъекции.
  • Валидация и санация ввода: Проверяйте и очищайте пользовательские данные на стороне сервера, используя белые списки разрешённых символов или форматов.
  • HttpOnly флаг для кук: Устанавливайте флаг HttpOnly для сессионных и других критичных кук, чтобы сделать их недоступными для JavaScript, что предотвратит их кражу через XSS.

Ответ 18+ 🔞

Бля, ну слушай, история про XSS — это пиздопроебибна тема, если честно. Представь: сидит себе пользователь, чай пьёт, на сайт зашёл, а там какой-то пидарас шерстяной через дыру в коде свой скрипт впихнул. И этот скрипт в браузере жертвы выполняется, как будто он от самого сайта пришёл. Вот это и есть Cross-Site Scripting, ёпта. Удивление пиздец, когда узнаёшь, как это просто и страшно.

Какие бывают разновидности этой хуйни:

  1. Хранимый (Stored). Это самый наглый вид. Злоумышленник свой гадкий код прямо на сервер заливает — в комментарий, в профиль, в базу данных. И он там сидит, как ядрёна вошь, пока каждый следующий пользователь страницу не откроет и не подхватит заразу. Автоматическая залупа конская.
  2. Отражённый (Reflected). Тут уже нужна социальная инженерия. Злодей делает специальную ссылку со скриптом внутри, типа site.com/search?q=<script>alert('лох')</script>. Кидает её в личку какому-нибудь лоху. Лох кликает, скрипт в ответе от сервера отражается и — бац! — выполняется. Но только в его сессии. Овердохуища вреда можно нанести, если ссылку массово раскидать.
  3. DOM-based. А вот это уже хитрая жопа. Тут сервер вроде ни при чём, вся движуха — в браузере у пользователя. JavaScript на странице берёт данные из управляемого источника (например, из фрагмента URL после решётки #) и, не подумав, вставляет их в DOM. Получается локальный взрыв в одном отдельно взятом браузере. Чёрта в душу разработчикам, которые так косячат.

Смотри, как это выглядит в коде, если делать по-уродски (PHP):

// Опасно, блядь! Берём что пришло из GET и суём прямо в HTML.
echo '<div>Привет, ' . $_GET['username'] . '!</div>';

Если в username передать <script>console.log(document.cookie)</script>, то приветствие превратится в ворующую куки пакость. Доверия ебать ноль к такому коду.

Как защищаться, чтобы не было мучительно больно:

  • Экранирование, ёб твою мать! Это святое. Перед тем как что-то пользовательское в HTML вывести, пропусти через htmlspecialchars. Это как надеть презерватив на данные.
    // Правильно, чувак! Теперь теги превратятся в безобидные каракули.
    echo '<div>Привет, ' . htmlspecialchars($_GET['username'], ENT_QUOTES | ENT_HTML5, 'UTF-8') . '!</div>';
  • Content Security Policy (CSP). Это мощнейшая штука. Ты через HTTP-заголовок говоришь браузеру: «Слушай сюда, скрипты грузи ТОЛЬКО оттуда-то и оттуда-то». Даже если злодей протащит свой скрипт, браузер его выполнять не станет, потому что он не из белого списка. Волнение ебать, но оно того стоит.
  • Проверяй и чисти всё, что приходит от пользователя. Не верь никому, особенно данным извне. Используй белые списки разрешённых символов. Сам от себя охуеешь, сколько говна отсеешь.
  • Флаг HttpOnly для кук. Выставляй его для сессионных кук. Это значит, что к этим кукам из JavaScript доступа не будет. Даже если скрипт выполнится, украсть сессию не выйдет. Просто и гениально.

В общем, XSS — это не шутки. Если на своём проекте найдёшь такую дыру, срочно чини, пока гомосеки не налетели.