Какие знаешь способы защиты от XSS

Ответ

  1. Экранирование (escaping) – преобразование спецсимволов в HTML-сущности (например, <&lt;).
    Пример:
    const escaped = str.replace(/</g, '&lt;').replace(/>/g, '&gt;');
  1. Использование textContent вместо innerHTML – предотвращает интерпретацию HTML/JS.
    element.textContent = userInput; // безопасно
  1. Content Security Policy (CSP) – HTTP-заголовок, ограничивающий источники скриптов, стилей и т.д.
    Пример заголовка:
    Content-Security-Policy: default-src 'self'
  1. Библиотеки для санитизации – например, DOMPurify:
    const clean = DOMPurify.sanitize(userInput);
  1. HttpOnly и Secure флаги для кук – защищает от кражи кук через JS.

  2. Валидация и ограничение ввода – например, разрешать только определенные символы.

Для React/Vue/Angular: фреймворки автоматически экранируют данные в шаблонах, но важно избегать dangerouslySetInnerHTML (React) или v-html (Vue) без санитизации.

Ответ 18+ 🔞

Ну ты смотри, какие умные головы придумали, чтобы нас, разработчиков, не выебали на ровном месте! XSS — это ж как геморрой, только в коде. Сидит где-то в твоём приложении и ждёт, когда ты расслабишься, чтобы впендюрить свой скрипт. А потом — бац! — и у тебя все куки уплыли к какому-то пидарасу шерстяному. Так что слушай сюда, как от этого чуда обороняться.

Первое, что надо усвоить — экранирование. Это когда ты все эти ебучие угловые скобки и амперсанды превращаешь в безобидные буковки. Типа < становится &lt;. Делается это просто, но мозг выносит, если делать вручную.

const escaped = str.replace(/</g, '&lt;').replace(/>/g, '&gt;');

Но реально, кто ж так будет делать? Только мазохист. Поэтому второе правило — не лезь в innerHTML с грязными данными. Есть же textContent! Он не пытается быть умным и просто вставляет текст как есть, не парся его как HTML.

element.textContent = userInput; // вот так безопасно, блядь

Дальше идёт Content Security Policy (CSP). Это такая тяжёлая артиллерия. Ты говоришь браузеру: "Слушай, дружок, скрипты грузи только отсюда, стили — оттуда, а всё остальное — нахуй". В заголовках это выглядит как магия:

Content-Security-Policy: default-src 'self'

Это значит — всё только со своего сервака. Попробуй впендюрить скрипт с левого домена — браузер его посылает на три весёлые буквы.

Если уж совсем припёрло и надо вставить HTML, который тебе прислал пользователь (ну, там, rich-text редактор), то используй библиотеки для санитизации. DOMPurify, например. Он как хороший сантехник — вычищает всё дерьмо, оставляя только безопасные теги.

const clean = DOMPurify.sanitize(userInput); // вот теперь можно и в innerHTML

Про куки не забудь! Ставь им флаги HttpOnly и Secure. Первый не даёт JavaScript'у до них достучаться, второй — чтобы летали только по HTTPS. Красть их станет в разы сложнее, хоть и не невозможно.

Ну и, само собой, валидация. Если поле для номера телефона — пусть там будут только цифры, плюс и скобки. Не надо давать пользователям вводить всякую хуйню, они же её потом и отправят, распиздяи.

Для фреймворков (React, Vue, Angular) — там обычно всё заэкранировано автоматически. Но есть лазейки! В React — dangerouslySetInnerHTML, в Vue — v-html. Это прям кричащие названия, ёпта! "Опасно установить внутренний HTML" — ну как будто тебя предупреждают: "Чувак, не надо, там пиздец будет". Если уж юзаешь — пропусти данные через санитизатор, будь не мудаком.

Короче, суть в чём: не доверяй никому. Ни пользователю, ни себе в пятницу вечером. Всегда предполагай, что входящие данные — это бомба, и обезвреживай их, пока не стало поздно. А то будет как в том анекдоте: "Ваш сайт взломали". — "И что сделали?" — "Ничего, просто на главной странице теперь летает dickbutt". Волнение ебать!